package com.turing.post.salesmanage.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.turing.post.capitalaccounts.util.BankAccountDetail;
import com.turing.post.capitalaccounts.util.BankAccountDetailDao;
import com.turing.post.capitalaccounts.util.SaleCapitalDetail;
import com.turing.post.capitalaccounts.util.SaleCapitalDetailDao;
import com.turing.post.cardmanagement.util.CardClassic;
import com.turing.post.cardmanagement.util.CardClassicDao;
import com.turing.post.cardmanagement.util.CardFace;
import com.turing.post.cardmanagement.util.CardFaceDao;
import com.turing.post.cardmanagement.util.CardManaApplicationException;
import com.turing.post.cardmanagement.util.CardStock;
import com.turing.post.cardmanagement.util.CardStockDao;
import com.turing.post.cardmanagement.util.MakeCardControl;
import com.turing.post.cardmanagement.util.MakeCardControlDao;
import com.turing.post.cardmanagement.util.SaleCardStockDetail;
import com.turing.post.cardmanagement.util.SaleCardStockDetailDao;
import com.turing.post.cardmanagement.util.SalesGetCardOrder;
import com.turing.post.cardmanagement.util.SalesGetCardOrderDao;
import com.turing.post.common.util.BlackList;
import com.turing.post.common.util.BlackListDao;
import com.turing.post.common.util.Global;
import com.turing.post.common.util.IdType;
import com.turing.post.common.util.IdTypeDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOpUser;
import com.turing.post.common.util.SysOpUserDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.IssueBranch;
import com.turing.post.organization.util.IssueBranchDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.organization.util.IssueFeePolicy;
import com.turing.post.organization.util.IssueFeePolicyBusiness;
import com.turing.post.organization.util.IssueFeePolicyLimit;
import com.turing.post.organization.util.IssueFeePolicyLimitDao;
import com.turing.post.organization.util.SaleBranch;
import com.turing.post.organization.util.SaleBranchDao;
import com.turing.post.organization.util.SysBranch;
import com.turing.post.organization.util.VoucherBusinessBind;
import com.turing.post.organization.util.VoucherBusinessBindDao;
import com.turing.post.organization.util.VoucherStock;
import com.turing.post.organization.util.VoucherStockDao;
import com.turing.post.organization.util.VoucherStockDetail;
import com.turing.post.organization.util.VoucherStockDetailDao;
import com.turing.post.report.util.BinaryFileInfo;
import com.turing.post.report.util.BinaryFileInfoDao;
import com.turing.post.salesmanage.util.PersonalCustom;
import com.turing.post.salesmanage.util.PersonalCustomDao;
import com.turing.post.salesmanage.util.Profession;
import com.turing.post.salesmanage.util.ProfessionDao;
import com.turing.post.salesmanage.util.SaleOrder;
import com.turing.post.salesmanage.util.SaleOrderActionDetail;
import com.turing.post.salesmanage.util.SaleOrderActionDetailDao;
import com.turing.post.salesmanage.util.SaleOrderBusiness;
import com.turing.post.salesmanage.util.SaleOrderCardDetail;
import com.turing.post.salesmanage.util.SaleOrderCardDetailDao;
import com.turing.post.salesmanage.util.SaleOrderDao;
import com.turing.post.salesmanage.util.SaleOrderPaidDetail;
import com.turing.post.salesmanage.util.SaleOrderPaidDetailDao;
import com.turing.post.salesmanage.util.SaleOrderRealNameDetail;
import com.turing.post.salesmanage.util.SaleOrderRealNameDetailDao;
import com.turing.post.salesmanage.util.SaleOrderSalesDetail;
import com.turing.post.salesmanage.util.SaleOrderSalesDetailDao;
import com.turing.post.salesmanage.util.SalesManageApplicationException;
import com.turing.post.salesmanage.util.SalesManageRespCode;
import com.turing.post.util.IDCardCheck;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.PCPSWebInput;
import com.turing.post.util.SHA1;

/**
 * 销售单业务员处理
 * 
 * @author zxp
 * @Dec 23, 2012
 */
@Stateless(mappedName = "salesmanage.impl.SaleOrderBusinessImpl")
@Remote
@Local
public class SaleOrderBusinessImpl implements SaleOrderBusiness {

	@EJB(mappedName = "salesmanage.impl.SaleOrderDaoImpl")
	private SaleOrderDao saleOrderDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderActionDetailDaoImpl")
	private SaleOrderActionDetailDao saleOrderActionDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderSalesDetailDaoImpl")
	private SaleOrderSalesDetailDao saleOrderSalesDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderCardDetailDaoImpl")
	private SaleOrderCardDetailDao saleOrderCardDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderPaidDetailDaoImpl")
	private SaleOrderPaidDetailDao saleOrderPaidDetailDaoImpl;

	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao commonDaoImpl;

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;

	@EJB(mappedName = "common.impl.SysOpUserDaoImpl")
	private SysOpUserDao sysOpUserDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.CardStockDaoImpl")
	private CardStockDao cardStockDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.CardFaceDaoImpl")
	private CardFaceDao cardFaceDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.MakeCardControlDaoImpl")
	private MakeCardControlDao makeCardControlDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.CardClassicDaoImpl")
	private CardClassicDao cardClassicDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.SaleCardStockDetailDaoImpl")
	private SaleCardStockDetailDao saleCardStockDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderRealNameDetailDaoImpl")
	private SaleOrderRealNameDetailDao saleOrderRealNameDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.PersonalCustomDaoImpl")
	private PersonalCustomDao personalCustomDaoImpl;

	@EJB(mappedName = "common.impl.BlackListDaoImpl")
	private BlackListDao blackListDaoImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "organization.impl.SaleBranchDaoImpl")
	private SaleBranchDao saleBranchDaoImpl;

	@EJB(mappedName = "organization.impl.IssueBranchDaoImpl")
	private IssueBranchDao issueBranchDaoImpl;

	@EJB(mappedName = "common.impl.IdTypeDaoImpl")
	private IdTypeDao idTypeDaoImpl;

	@EJB(mappedName = "report.impl.BinaryFileInfoDaoImpl")
	private BinaryFileInfoDao binaryFileInfoDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.SaleCapitalDetailDaoImpl")
	private SaleCapitalDetailDao saleCapitalDetailDaoImpl;

	@EJB(mappedName = "organization.impl.VoucherStockDaoImpl")
	private VoucherStockDao voucherStockDaoImpl;

	@EJB(mappedName = "organization.impl.VoucherStockDetailDaoImpl")
	private VoucherStockDetailDao voucherStockDetailDaoImpl;

	@EJB(mappedName = "organization.impl.IssueFeePolicyBusinessImpl")
	private IssueFeePolicyBusiness issueFeePolicyBusinessImpl;

	@EJB(mappedName = "organization.impl.VoucherBusinessBindDaoImpl")
	private VoucherBusinessBindDao voucherBusinessBindImpl;

	@EJB(mappedName = "salesmanage.impl.ProfessionDaoImpl")
	private ProfessionDao professionDaoImpl;

	@EJB(mappedName = "organization.impl.IssueFeePolicyLimitDaoImpl")
	private IssueFeePolicyLimitDao issueFeePolicyLimitDaoImpl;

	@EJB(mappedName = "cardmanagement.impl.SalesGetCardOrderDaoImpl")
	private SalesGetCardOrderDao sgcoDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.BankAccountDetailDaoImpl")
	private BankAccountDetailDao bankAccountDetailDaoImpl;

	@EJB(mappedName = "salesmanage.impl.SaleOrderBusinessImpl")
	private SaleOrderBusiness saleOrderBusinessImpl;

	private String getSysBranchType(String branchNo) {
		String s = branchNo.substring(6, 8);
		if ("98".equals(s)) {
			return SysBranch.SYSBRANCH_SALEBRANCH;
		}
		return "";
	}

	/**
	 * 异常抛出方法
	 * 
	 * @param error
	 * @throws PCPSApplicationException
	 */
	private void errException(String error) throws PCPSApplicationException {
		throw new SalesManageApplicationException(
				SalesManageApplicationException.ERRCODE_CATEGORY_APPLICATION,
				SalesManageRespCode.SALESBUSINESS_ARGS_NULL, error);
	}

	/**
	 * 销售单主管授权
	 * 
	 * @param webInput
	 * @param autherName
	 * @param autherPass
	 * @throws PCPSApplicationException
	 */
	public BigInteger authCreateSaleOrder(PCPSWebInput webInput,
			String autherName, String autherPass)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(autherName) || PCPSUtil.isEmpty(autherPass)) {
			errException("请销售机构授权主管授权用户/密码为空!");
		} else {
			SysOpUser su = sysOpUserDaoImpl
					.getSysOpUserByOperLogonName(autherName);
			if (su == null) {
				errException("销售机构主管授权用户不存在!");
			} else if (su.getOperId().compareTo(webInput.getOperId()) == 0) {
				errException("销售机构主管授权用户不能为当前销售用户!");
			} else {
				String password = new SHA1()
						.getDigestOfString((autherName + autherPass).getBytes());
				if (!su.getOperPasswd().equals(password)) {
					errException("销售机构主管授权密码错误!");
				} else {
					// 设置授权用户
					return su.getOperId();
				}
			}
		}
		return BigInteger.ZERO;
	}

	/**
	 * 判断销售单付款是否包含现金
	 * 
	 * @param saleOrders
	 * @return
	 */
	@Override
	public boolean checkCashSaleOrder(BigInteger[] saleOrders) {
		boolean result = false;
		List<SaleOrderPaidDetail> sopdList = null;
		if (saleOrders == null || saleOrders.length < 1) {
			return result;
		}
		for (BigInteger b : saleOrders) {
			sopdList = saleOrderPaidDetailDaoImpl
					.getSaleOrderPaidDetailListBySaleOrderId(b);
			if (sopdList != null && sopdList.size() > 0) {
				// 销售单购卡中有现金付款
				for (SaleOrderPaidDetail sopd : sopdList) {
					// 现金购卡
					if (sopd.getPaidType().equals(
							SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
						result = true;
					}
				}
			}
		}
		return result;
	}

	@Override
	public void authSaleOrderCard(PCPSWebInput webInput,
			BigInteger[] saleOrderIds) throws PCPSApplicationException {
		if (webInput == null || PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("操作员或归属机构为空!");
		}
		if (saleOrderIds == null || saleOrderIds.length < 1) {
			errException("未选择审核的销售单!");
		}
		SaleOrder so = null;
		List<SaleOrderCardDetail> socdList = null;
		for (BigInteger b : saleOrderIds) {
			so = saleOrderDaoImpl.getSaleOrderBySaleOrderId(b);
			if (!so.getOrderStatus().equals(
					SaleOrder.SaleOrder_OrderStatus_AuthMoney)) {
				errException("销售单" + so.getSaleOrderSeqNo() + "状态不为资金已审核!");
			}
			so.setOrderStatus(SaleOrder.SaleOrder_OrderStatus_AuthCard);
			// 销售单状态迁移明细
			insertSaleOrderActionDetail(so.getSaleOrderId(), webInput
					.getOperId(), SaleOrder.SaleOrder_OrderStatus_AuthMoney,
					SaleOrder.SaleOrder_OrderStatus_AuthCard,
					SaleOrderActionDetail.ACTIONTYPE_authCard, "销售单卡审核");
			saleOrderDaoImpl.updateSaleOrder(so);
			// 修改卡库存状态
			socdList = saleOrderCardDetailDaoImpl
					.getSaleOrderCardDetailListBySaleOrderId(b);
			// 插入售卡明细
			for (SaleOrderCardDetail socd : socdList) {
				cardStockDaoImpl.updateCardStock(socd.getBatchNo(), socd
						.getStartCardSeqNo(), socd.getEndCardSeqNo(),
						CardStock.CARDSTOCK_STATUS_WAITACTIVATE);
			}
		}
	}

	// 销售单资金审核
	@SuppressWarnings("unchecked")
	@Override
	public void authSaleOrderMoney(PCPSWebInput webInput,
			BigInteger[] saleOrderIds) throws PCPSApplicationException {
		if (webInput == null || PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("操作员或归属机构为空!");
		}
		if (saleOrderIds == null || saleOrderIds.length < 1) {
			errException("未选择审核的销售单!");
		}
		for (BigInteger b : saleOrderIds) {
			saleOrderBusinessImpl.authOneSaleOrderMoney(webInput, b);
		}
	}

	// 单个销售单资金审核
	@Override
	public void authOneSaleOrderMoney(PCPSWebInput webInput, BigInteger b)
			throws PCPSApplicationException {
		if (webInput == null || PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("操作员或归属机构为空!");
		}
		SaleOrder so = saleOrderDaoImpl.getSaleOrderBySaleOrderId(b);
		if (!so.getOrderStatus().equals(SaleOrder.SaleOrder_OrderStatus_Sent)) {
			errException("销售单" + so.getSaleOrderSeqNo() + "状态不为已上送状态!");
		}
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(so
				.getSaleBranchNo());
		// 销售单付款信息列表
		List<SaleOrderPaidDetail> sodpList = saleOrderPaidDetailDaoImpl
				.getSaleOrderPaidDetailListBySaleOrderId(b);
		// 授信购卡销售单
		if (SaleOrder.SaleOrder_PaidType_Credit.equals(so.getPaidType())) {
			// 未有付款信息
			if (sodpList == null || sodpList.size() < 1) {
				// 销售单已核实资金
				so.setOrderStatus(SaleOrder.SaleOrder_OrderStatus_AuthMoney);
				so.setRemark(PCPSUtil.isEmpty(so.getRemark()) ? "" : so
						.getRemark()
						+ " 销售单资金已审核");
				// 销售单状态迁移明细
				insertSaleOrderActionDetail(so.getSaleOrderId(), webInput
						.getOperId(), SaleOrder.SaleOrder_OrderStatus_Sent,
						SaleOrder.SaleOrder_OrderStatus_AuthMoney,
						SaleOrderActionDetail.ACTIONTYPE_authMoney, "销售单资金审核");
				saleOrderDaoImpl.updateSaleOrder(so);
			} else {
				authMoney(webInput, so, sodpList, sb);
			}
		} else {
			authMoney(webInput, so, sodpList, sb);
		}
	}

	private void authMoney(PCPSWebInput webInput, SaleOrder so,
			List<SaleOrderPaidDetail> sodpList, SaleBranch sb)
			throws PCPSApplicationException {
		// 销售单现金付款
		BigInteger cashAll = BigInteger.ZERO;
		// 销售单现金手续费金额合计
		BigInteger feeAll = BigInteger.ZERO;
		// 销售单转账付款
		BigInteger tranAll = BigInteger.ZERO;
		// 循环销售单付款信息
		SaleOrderPaidDetail sopd = null;
		BankAccountDetail tranBad = null;
		boolean tag = false;
		// 先处理转账类付款信息
		for (int i = 0; i < sodpList.size(); i++) {
			sopd = sodpList.get(i);
			// 非现金转账购卡付款信息
			if (!sopd.getPaidType().equals(
					SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
				tranBad = bankAccountDetailDaoImpl
						.getBankAccountDetailByID(sopd.getBankAccDetailId());
				if (!tranBad.getStauts().equals(
						BankAccountDetail.STATUS_AUTOCHECK)
						&& !tranBad.getStauts().equals(
								BankAccountDetail.STATUS_MANUALLYCHECK)) {
					errException("银行凭证号" + tranBad.getVoucherNo() + "对应记账金额"
							+ get100(tranBad.getVoucherAmount()) + "未核对!");
				}
				if (tranBad.getVoucherAmount().compareTo(
						sopd.getPaidAmount().add(tranBad.getDebitAmount())) < 0) {
					errException("银行凭证号"
							+ tranBad.getVoucherNo()
							+ "对应记账记录凭证金额"
							+ get100(tranBad.getVoucherAmount())
							+ "不可小于销售单转账付款金额"
							+ get100(sopd.getPaidAmount())
							+ "与累计借方发生额"
							+ get100(tranBad.getDebitAmount())
							+ "之和"
							+ get100(sopd.getPaidAmount().add(
									tranBad.getDebitAmount())));
				}
				tranBad.setDebitAmount(tranBad.getDebitAmount().add(sopd.getPaidAmount()));// 银行入账流水累计贷方发生额;
				bankAccountDetailDaoImpl.modifyBankAccountDetail(tranBad);// 每次更新转账银行入账流水贷方发生额
				tranAll = tranAll.add(sopd.getPaidAmount());// 销售单转账金额合计
			} else {
				tag = true;// 含有现金付款
				// 销售单现金付款信息
				if (SaleOrderPaidDetail.PAIDDETAIL_paidClass_sale.equals(sopd
						.getPaidClass())) {// 只合计现金销售款
					cashAll = cashAll.add(sopd.getPaidAmount());// 销售单现金销售款金额合计
				} else if (SaleOrderPaidDetail.PAIDDETAIL_paidClass_fee
						.equals(sopd.getPaidClass())) {
					feeAll = feeAll.add(sopd.getPaidAmount());// 销售单现金手续费金额合计
				}
			}
		}
		if (tag) {
			// sb.getAlreadyCheckCash()只含有销售款和充值款
			if (sb.getAlreadyCheckCash().compareTo(cashAll) < 0) {
				errException("销售机构已核实资金金额" + get100(sb.getAlreadyCheckCash())
						+ "不可小于销售单" + so.getSaleOrderSeqNo() + "现金销售款金额合计"
						+ get100(cashAll));
			}
			// 更新销售机构
			sb.setAlreadyCheckCash(sb.getAlreadyCheckCash().subtract(cashAll));
			saleBranchDaoImpl.updateSaleBranch(sb);
		}
		// 销售单已核实资金
		so.setTotalCheckAmount(tranAll.add(cashAll).add(feeAll));
		so.setOrderStatus(SaleOrder.SaleOrder_OrderStatus_AuthMoney);
		so.setRemark(PCPSUtil.isEmpty(so.getRemark()) ? "" : so.getRemark()
				+ " 销售单资金已审核");
		// 销售单状态迁移明细
		insertSaleOrderActionDetail(so.getSaleOrderId(), webInput.getOperId(),
				SaleOrder.SaleOrder_OrderStatus_Sent,
				SaleOrder.SaleOrder_OrderStatus_AuthMoney,
				SaleOrderActionDetail.ACTIONTYPE_authMoney, "销售单资金审核");
		saleOrderDaoImpl.updateSaleOrder(so);
	}

	/**
	 * 打包上送销售单
	 * 
	 * @param webInput
	 * @param saleOrderIds
	 * @throws PCPSApplicationException
	 */
	public void updateSaleOrderActivateBranchNo(PCPSWebInput webInput,
			BigInteger[] saleOrderIds, BigInteger bankAccDetailId)
			throws PCPSApplicationException {
		if (webInput == null || PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("操作员或归属机构为空!");
		}
		if (saleOrderIds == null || saleOrderIds.length < 1) {
			errException("未选择激活的销售单!");
		}
		String activateBranchNo = getActivateBranchNo(webInput
				.getOperBranchNo());
		if (PCPSUtil.isEmpty(activateBranchNo)) {
			errException("未获取到上级激活机构!");
		}
		if (activateBranchNo.length() == 6) {
			errException("激活机构必须为发卡商机构!");
		}
		SaleOrder so = null;
		String res = "";
		// List<SaleOrderPaidDetail> sopdList = null;
		// BigInteger allCash = BigInteger.ZERO;// 总现金金额
		// HashMap<BigInteger, BigInteger> map = new HashMap<BigInteger,
		// BigInteger>();
		List<SaleOrder> orderList = new ArrayList<SaleOrder>();
		for (BigInteger b : saleOrderIds) {
			so = saleOrderDaoImpl.getSaleOrderBySaleOrderId(b);
			orderList.add(so);
			// sopdList = saleOrderPaidDetailDaoImpl
			// .getSaleOrderPaidDetailListBySaleOrderId(so
			// .getSaleOrderId());
			// if (sopdList != null && sopdList.size() > 0) {
			// // 销售单购卡中有现金付款
			// for (SaleOrderPaidDetail sopd : sopdList) {
			// // 现金购卡
			// if (sopd.getPaidType().equals(
			// SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
			// map.put(so.getSaleOrderId(), so.getSaleOrderId());
			// allCash = allCash.add(sopd.getPaidAmount());
			// }
			// }
			// }
			res += b.toString() + ",";
		}
		// if (allCash.compareTo(BigInteger.ZERO) > 0) {
		// if (bankAccDetailId == null) {
		// errException("打包提交销售单中含有现金购卡，必须录入现金上缴流水号!");
		// }
		// BankAccountDetail bad = bankAccountDetailDaoImpl
		// .getBankAccountDetailByID(bankAccDetailId);
		// if (bad == null) {
		// errException("输入的现金上缴流水号" + bankAccDetailId + "系统中不存在!");
		// }
		// if (allCash.compareTo(bad.getVoucherAmount()) > 0) {
		// errException("打包提交销售单现金购卡总金额" + get100(allCash) + "不可大于现金上缴金额"
		// + get100(bad.getVoucherAmount()));
		// }
		// }
		for (SaleOrder saleOrder : orderList) {
			saleOrder.setActivateBranchNo(activateBranchNo);
			// 含有现金购卡销售单设置现金上缴银行入账流水号
			// if (map.get(saleOrder.getSaleOrderId()) != null) {
			// saleOrder.setBankAccDetailId(bankAccDetailId);
			// }
			// 销售单状态迁移明细
			insertSaleOrderActionDetail(saleOrder.getSaleOrderId(), webInput
					.getOperId(), saleOrder.getOrderStatus(),
					SaleOrder.SaleOrder_OrderStatus_Sent,
					SaleOrderActionDetail.ACTIONTYPE_put, "打包上送销售单");
			saleOrder.setOrderStatus(SaleOrder.SaleOrder_OrderStatus_Sent);
			// 修改
			saleOrderDaoImpl.updateSaleOrder(saleOrder);
		}
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "销售单打包上送", "销售单流水号："
						+ res.substring(0, res.length() - 1));
	}

	private String getActivateBranchNo(String saleBranchNo) {
		SaleBranch sb = saleBranchDaoImpl
				.getSaleBranchBySaleBranchNo(saleBranchNo);
		// 发卡商机构
		IssueBranch ib = issueBranchDaoImpl.getIssueBranchByIssueBranchNo(sb
				.getIssueBranchNo());
		if (ib.getAllowActivate().equals(
				IssueBranch.ISSUEBRANCH_ALLOWACTIVATE_YES)) {
			return ib.getIssueBranchNo();
		} else if (ib.getSuperIssueBranchNo() != null) {
			IssueBranch suIb = issueBranchDaoImpl
					.getIssueBranchByIssueBranchNo(ib.getSuperIssueBranchNo());
			if (suIb.getAllowActivate().equals(
					IssueBranch.ISSUEBRANCH_ALLOWACTIVATE_YES)) {
				return suIb.getIssueBranchNo();
			} else if (suIb.getSuperIssueBranchNo() != null) {
				IssueBranch susuIb = issueBranchDaoImpl
						.getIssueBranchByIssueBranchNo(suIb
								.getSuperIssueBranchNo());
				if (susuIb.getAllowActivate().equals(
						IssueBranch.ISSUEBRANCH_ALLOWACTIVATE_YES)) {
					return susuIb.getIssueBranchNo();
				} else if (susuIb.getSuperIssueBranchNo() != null) {
					IssueBranch sususuIb = issueBranchDaoImpl
							.getIssueBranchByIssueBranchNo(susuIb
									.getSuperIssueBranchNo());
					return sususuIb.getIssueBranchNo();
				} else {
					return null;
				}
			} else {
				return null;
			}
		} else {
			return null;
		}
	}

	@Override
	public void updateSaleOrderVoucherNo(PCPSWebInput webInput,
			BigInteger saleOrderId, String voucherNo)
			throws PCPSApplicationException {
		String businessType = VoucherBusinessBind.BusinessType_01;
		List<VoucherBusinessBind> vbbList = voucherBusinessBindImpl
				.getVoucherBusinessBindByBusinessType(webInput, businessType,
						-1);
		if (vbbList == null || vbbList.size() < 1) {
			errException("未找到销售业务对应凭证种类!");
		}
		// 凭证种类Id
		BigInteger voucherId = vbbList.get(0).getVoucherId();
		// 插入对象为null
		if (saleOrderId == null || webInput == null
				|| PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("操作员或归属机构为空!");
		}
		SaleOrder so = saleOrderDaoImpl.getSaleOrderForUpdate(saleOrderId);
		if (so == null) {
			errException("销售单编号错误!");
		} else {
			VoucherStock vs = new VoucherStock();
			vs.setVoucherId(voucherId);
			vs.setVoucherNo(voucherNo);
			VoucherStock serchVS = voucherStockDaoImpl.getVoucherStock(vs);
			if (serchVS == null) {
				errException("凭证信息不存在或状态异常!");
			} else if (!VoucherStock.Status_0.equals(serchVS.getStatus())) {
				String str = ("1".equals(serchVS.getStatus())) ? "在途" : ("9"
						.equals(serchVS.getStatus())) ? "丢失、损坏等" : "";
				errException("凭证信息不存在或状态异常!" + str);
			} else {
				// 更新凭证库存
				serchVS.setStatus(VoucherStock.Status_2);
				voucherStockDaoImpl.updateVoucherStockByStatus(serchVS);
				// 插入库存出入库明细
				VoucherStockDetail voucherStockDetail = new VoucherStockDetail();
				voucherStockDetail.setIoOrderId(saleOrderId);
				voucherStockDetail.setIssueCompanyNo(PCPSUtil
						.getIssueCompanyNo(webInput));
				voucherStockDetail.setBranchNo(webInput.getOperBranchNo());
				IssueCompany ic = issueCompanyDaoImpl
						.getIssueCompanyByIssueCompanyNo(PCPSUtil
								.getIssueCompanyNo(webInput));
				voucherStockDetail.setTranDate(ic.getTranDate());
				voucherStockDetail.setTranTime(commonDaoImpl
						.getDatabaseSysTime());
				voucherStockDetail.setVoucherId(voucherId);
				voucherStockDetail.setStartVoucherNo(voucherNo);
				voucherStockDetail.setEndVoucherNo(voucherNo);
				voucherStockDetail.setCount(1);
				voucherStockDetail.setTranType(VoucherStockDetail.Status_4);
				voucherStockDetail.setOperId(webInput.getOperId());

				voucherStockDetailDaoImpl
						.insertVoucherStockDetail(voucherStockDetail);
			}
			so.setVoucherId(voucherId);
			so.setVoucherNo(voucherNo);
			saleOrderDaoImpl.updateSaleOrder(so);
		}
	}

	// 创建销售单录入全部参数
	@SuppressWarnings("unchecked")
	@Override
	public SaleOrder createSaleOrder(PCPSWebInput webInput,
			SaleOrder saleOrder, List<SaleOrderCardDetail> cardDetailList,
			List<SaleOrderSalesDetail> salesDetailList,
			List<SaleOrderRealNameDetail> realNameList,
			List<SaleOrderPaidDetail> paidDetailList)
			throws PCPSApplicationException {
		// 销售单信息=============
		saleOrder = getSaleOrder(webInput, saleOrder);
		// 发卡商
		IssueCompany ic = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(saleOrder.getSaleBranchNo()));
		// 判断是否为日终(交易)状态
		if (ic == null
				|| ic.getStatus().equals(
						IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			errException("销售单所在机构未有归属发卡商或发卡商正在日终禁止销售!");
		}
		String saleBranchNo = saleOrder.getSaleBranchNo();
		// 销售时间
		Date now = commonDaoImpl.getDatabaseSysTime();
		saleOrder.setSaleTime(now);
		// 设置销售单为已出库状态
		saleOrder.setOrderStatus(SaleOrder.SALEORDER_ORDERSTATUS_LIBRARY);
		// 销售单售卡信息=============
		List<SaleOrderCardDetail> insertSocdList = new ArrayList<SaleOrderCardDetail>();
		SaleOrderCardDetail insertSocd = null;
		Integer totalCardCount = 0;// 销售单总售卡张数
		BigInteger totalSaleAmount = BigInteger.ZERO;// 销售单总售卡金额
		if (cardDetailList == null || cardDetailList.size() < 1) {
			errException("销售单未添加售卡信息!");
		}
		CardClassic cc = null;// 卡种类
		// 需要实名的卡,里面为卡顺序号
		List<String> realNameCardList = new ArrayList<String>();

		String batchNo = null;
		MakeCardControl mcc = null;
		IssueFeePolicy ifp = null;
		// 计算出来手续费合计
		BigInteger allFee = BigInteger.ZERO;
		for (SaleOrderCardDetail socd : cardDetailList) {
			insertSocd = getSaleOrderCardDetail(saleOrder.getBtnStatus(), ic,
					socd, saleBranchNo);
			batchNo = insertSocd.getBatchNo();
			if (socd.getStartCardSeqNo().trim().length() < 18) {
				batchNo = batchNo.substring(6, 12);
			}

			totalCardCount += insertSocd.getCardCount();
			totalSaleAmount = totalSaleAmount.add(insertSocd
					.getOrderLineTotal());
			insertSocdList.add(insertSocd);
			// 根据售卡明细列表中卡种类,判断是否实名
			String cardSeqNo = "";
			cc = cardClassicDaoImpl.getCardClassicByCardClassicId(socd
					.getCardClassicId());
			if (cc.getIsRealName().equals(
					CardClassic.CARDCLASSIC_STATUS_REALNAME)) {
				if (socd.getStartCardSeqNo().trim().length() < 18) {
					cardSeqNo = socd.getStartCardSeqNo().substring(6, 12);
				} else {
					cardSeqNo = socd.getStartCardSeqNo().substring(12, 18);
				}
				for (int i = 0; i < socd.getCardCount(); i++) {
					realNameCardList.add(batchNo
							+ String.format("%06d", Integer.parseInt(cardSeqNo)
									+ i));
				}
			} else if (ic.getEachCardOwnerLimit().compareTo(BigInteger.ZERO) > 0
					&& socd.getInitDeposit().compareTo(
							ic.getEachCardOwnerLimit().intValue()) > 0) {
				// 根据售卡面值判断是否实名 初始卡内金额和发卡商默认上限比对 强制实名
				if (socd.getStartCardSeqNo().trim().length() < 18) {
					cardSeqNo = socd.getStartCardSeqNo().substring(6, 12);
				} else {
					cardSeqNo = socd.getStartCardSeqNo().substring(12, 18);
				}
				for (int i = 0; i < socd.getCardCount(); i++) {
					realNameCardList.add(batchNo
							+ String.format("%06d", Integer.parseInt(cardSeqNo)
									+ i));
				}
			}
			batchNo = insertSocd.getBatchNo();
			// 制卡控制表
			mcc = makeCardControlDaoImpl.getMakeCardControlByBatchNo(batchNo);
			// 计算手续费
			if (true) {
				// 只计算每条售卡明细中第一张卡手续费
				ifp = issueFeePolicyBusinessImpl.calculateCardHolderFee(ic
						.getIssueCompanyNo(), saleBranchNo,
						IssueFeePolicy.IFPolicy_busiType_sale, null, socd
								.getStartCardSeqNo(), mcc.getCardFaceId(), cc
								.getCardClassicId(), null, ic.getTranDate(),
						new BigInteger(insertSocd.getInitDeposit().toString()),
						null);
				// 手续费合计
				allFee = allFee.add(ifp.getFee().multiply(
						new BigInteger(socd.getCardCount().toString())));
			} else {
				// 计算售卡明细中每一张卡手续费
			}
		}

		// 手续费上下限
		IssueFeePolicyLimit ifpl = issueFeePolicyLimitDaoImpl
				.getIssueFeePolicyLimitByCompNoAndTypeForEffective(ic
						.getIssueCompanyNo(),
						IssueFeePolicy.IFPolicy_busiType_sale);
		String ifplMsg = "";
		if (ifpl != null) {
			// 上限
			if (ifpl.getFeeUpperLimit().compareTo(BigInteger.ZERO) > 0) {
				if (allFee.compareTo(ifpl.getFeeUpperLimit()) > 0) {
					allFee = ifpl.getFeeUpperLimit();
					ifplMsg = "上限";
				}
			}
			// 下限
			if (ifpl.getFeeLowerLimit().compareTo(BigInteger.ZERO) > 0) {
				if (allFee.compareTo(ifpl.getFeeLowerLimit()) < 0) {
					allFee = ifpl.getFeeLowerLimit();
					ifplMsg = "下限";
				}
			}
		}

		// 售卡明细循环结束========
		if (insertSocdList == null || insertSocdList.size() < 1) {
			errException("销售单录入售卡明细为空!");
		}
		// 设置销售单SaleOrder内金额和卡张数
		saleOrder.setTotalCardCount(totalCardCount);
		saleOrder.setTotalSaleAmount(totalSaleAmount);
		// 销售单销售员信息=============
		BigInteger allSalesAmount = BigInteger.ZERO;// 营销金额
		if (salesDetailList != null) {
			for (SaleOrderSalesDetail sosd : salesDetailList) {
				allSalesAmount = allSalesAmount.add(sosd.getSalesAmount());
			}
			if (salesDetailList.size() > 0) {
				if (allSalesAmount.compareTo(totalSaleAmount) != 0) {
					errException("销售单营销员营销金额" + get100(allSalesAmount)
							+ "和销售单销售金额" + get100(totalSaleAmount) + "不符");
				}
			}
		}

		Global global = commonDaoImpl.getGlobalInfo();
		IdType idType = idTypeDaoImpl.getIdTypeByIdTypeName(global
				.getCommonIdTypeName());

		// 个人购卡销售单金额大于发卡商内设置金额,必须录入购卡人信息
		if (saleOrder.getBuyerType().equals(
				SaleOrder.SaleOrder_BuyerType_Person)) {
			if (ic.getPersonalBuyerLimit().compareTo(BigInteger.ZERO) > 0
					&& saleOrder.getTotalSaleAmount().compareTo(
							ic.getPersonalBuyerLimit()) > 0) {
				if (saleOrder.getPersonalBuyerId() == null) {
					errException("个人购卡金额大于发卡商个人购卡金额上限："
							+ get100(ic.getPersonalBuyerLimit())
							+ "，必须填写购卡人信息!");
				}
				PersonalCustom personal = personalCustomDaoImpl
						.getPersonalCustomByIdTypeAndIdNo(idType.getIdTypeId(),
								IssueCompany.IDNO);
				if (saleOrder.getPersonalBuyerId().compareTo(
						personal.getPersonalId()) == 0) {
					errException("个人购卡金额大于发卡商个人购卡金额上限："
							+ get100(ic.getPersonalBuyerLimit())
							+ "，购卡人不可默认为零散客户，必须录入实际够卡人信息!");
				}
			}
		}
		// 单位购卡销售单金额大于发卡商内设置金额,必须录入单位信息
		if (saleOrder.getBuyerType().equals(
				SaleOrder.SaleOrder_BuyerType_company)) {
			if (ic.getOrganizeBuyerLimit().compareTo(BigInteger.ZERO) > 0
					&& saleOrder.getTotalSaleAmount().compareTo(
							ic.getOrganizeBuyerLimit()) > 0) {
				if (saleOrder.getOrganizeBuyerId() == null) {
					errException("单位购卡金额大于发卡商单位购卡金额上限："
							+ get100(ic.getOrganizeBuyerLimit())
							+ "，必须填写购卡单位信息!");
				}
			}
		}

		if (realNameCardList.size() > 0) {
			if (saleOrder.getRealNameFileId() == null
					&& (realNameList == null || realNameList.size() < 1)) {
				errException("销售单售卡含有实名卡" + realNameCardList.get(0)
						+ ",未绑定实名信息!");
			}
		}

		// 解析插入excel实名信息并且直接插入数据库中
		// 身份证号和个人信息编号map
		HashMap<String, BigInteger> pcMap = new HashMap<String, BigInteger>();
		// 需要插入的实名绑定
		HashMap<String, SaleOrderRealNameDetail> insertSorndList = new HashMap<String, SaleOrderRealNameDetail>();
		if (saleOrder.getRealNameFileId() != null) {
			if (idType == null
					|| PCPSUtil.isEmpty(global.getPersonalCustomProfession())) {
				errException("证件类型中无身份证类型或默认职业编号为空!");
			}
			Profession pf = professionDaoImpl
					.getProfessionByProfessionNo(global
							.getPersonalCustomProfession());
			if (pf == null) {
				errException("默认职业编号系统中不存在!");
			}
			// 解析出来的持卡人excel文件数据 批次号，卡顺序号，卡号，持卡人，证件号 个人可以持有多张卡
			HashMap<String, SaleOrderRealNameDetail> cardRealMap = readRealNameFromExcel(saleOrder
					.getRealNameFileId());
			// 身份证号集合
			HashMap<String, String> idCardHM = new HashMap<String, String>();
			// 循环数据
			SaleOrderRealNameDetail sornd = null;
			for (Iterator it = cardRealMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry e = (Map.Entry) it.next();
				sornd = (SaleOrderRealNameDetail) e.getValue();
				idCardHM.put(sornd.getIdNo(), sornd.getName());// 证件号姓名map
			}
			// 插入个人信息
			String idCard = null;// 身份证号
			PersonalCustom pc = null;
			for (Iterator it = idCardHM.entrySet().iterator(); it.hasNext();) {
				Map.Entry e = (Map.Entry) it.next();
				idCard = e.getKey().toString();
				// 根据证件号查询PersonalCustom是否存在
				pc = personalCustomDaoImpl.getPersonalCustomByIdTypeAndIdNo(
						idType.getIdTypeId(), idCard);
				if (pc == null) {
					// 无个人信息需要添加
					pc = new PersonalCustom();
					pc.setIssueCompanyNo(ic.getIssueCompanyNo());
					pc.setProfessionId(pf.getProfessionId());// 职业

					if (idType.getIdTypeName().equals(
							global.getCommonIdTypeName())) {
						// 验证身份证
						IDCardCheck check = new IDCardCheck();
						if (!check.Verify(idCard)) {
							throw new SalesManageApplicationException(
									SalesManageApplicationException.ERRCODE_CATEGORY_APPLICATION,
									SalesManageRespCode.PERSONALCUSTOM_ARGS_NULL,
									"错误的身份证号码：" + idCard);
						}
					}

					pc.setIdTypeId(idType.getIdTypeId());
					pc.setIdNo(idCard);// 证件号
					pc.setNationCodeId(global.getChinaNationCodeId());// 国家/地区编码
					pc.setName(idCardHM.get(idCard));// 姓名
					pc.setRiskLevel(PersonalCustom.LOW_CUSTOM);// 风险等级
					BigInteger personalId = commonDaoImpl.getUniqueIntegerKey();
					pc.setPersonalId(personalId);
					personalCustomDaoImpl.insertPersonalCustomNoId(pc);
					pcMap.put(pc.getIdNo(), personalId);
				} else {
					// 已经存在的个人信息
					pcMap.put(idCard, pc.getPersonalId());
				}
			}
			// 获取需要插入的绑定列表
			for (Iterator it = cardRealMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry e = (Map.Entry) it.next();
				sornd = (SaleOrderRealNameDetail) e.getValue();
				// 客户编号
				sornd.setCustomId(pcMap.get(sornd.getIdNo()));
				insertSorndList.put(sornd.getCardSeqNo(), sornd);// 需要插入的实名信息关联表
			}
		}

		// 直接添加的销售单持卡人信息
		if (realNameList != null && realNameList.size() > 0) {
			// 从传入的实名列表中取实名信息
			// 非必须实名添加实名的卡
			for (SaleOrderRealNameDetail sornd : realNameList) {
				insertSorndList.put(sornd.getCardSeqNo(), sornd);// 需要插入的实名信息关联表
			}
		}

		SaleOrderRealNameDetail sornd = null;
		// 必须实名的卡
		for (String cardSeqNo : realNameCardList) {
			sornd = insertSorndList.get(cardSeqNo);
			if (sornd == null) {
				errException("销售单卡顺序号" + cardSeqNo + "未录入持卡人实名信息!");
			}
			// 直接使用购卡人充当持卡人
		}

		// 销售单付款信息=============
		List<SaleOrderPaidDetail> insertSopdList = new ArrayList<SaleOrderPaidDetail>();
		HashMap<Integer, SaleCapitalDetail> scdMap = new HashMap<Integer, SaleCapitalDetail>();
		SaleCapitalDetail scd = null;
		SaleOrderPaidDetail insertSopd = null;

		BigInteger alreayPaidAmount = BigInteger.ZERO;// 销售单总付款金额
		BigInteger paidAllFee = BigInteger.ZERO;// 销售单总付款手续费金额

		Integer cashAll = 0;// 现金购卡金额合计
		HashMap<BigInteger, BigInteger> bankAccDetailIdMap = new HashMap<BigInteger, BigInteger>();
		// 转账付款合计
		BigInteger tranAmount = BigInteger.ZERO;
		if (paidDetailList != null) {
			for (int i = 0; i < paidDetailList.size(); i++) {
				insertSopd = getSaleOrderPaidDetail(webInput, paidDetailList
						.get(i));
				insertSopd.setTranDate(ic.getTranDate());// 账务日期
				insertSopd.setTranTime(now);// 付款时间
				// 手续费付款金额
				if (insertSopd.getPaidClass().equals(
						SaleOrderPaidDetail.PAIDDETAIL_paidClass_fee)) {
					paidAllFee = paidAllFee.add(insertSopd.getPaidAmount());
				}
				alreayPaidAmount = alreayPaidAmount.add(insertSopd
						.getPaidAmount());
				scd = getSaleCapitalDetail(paidDetailList.get(i), ic, saleOrder
						.getSaleBranchNo(), webInput);
				if (scd != null) {
					scdMap.put(i, scd);
					cashAll += Integer
							.parseInt(scd.getCashDeposit().toString());
				} else {
					scdMap.put(i, null);
				}
				insertSopdList.add(insertSopd);
				// 转账付款
				if (!insertSopd.getPaidType().equals(
						SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
					tranAmount = tranAmount.add(insertSopd.getPaidAmount());
					// 银行转账凭证号
					bankAccDetailIdMap.put(insertSopd.getBankAccDetailId(),
							insertSopd.getBankAccDetailId());
				}

			}
		}
		BigInteger voucherAmount = BigInteger.ZERO;
		// 银行转账凭证号
		for (Iterator<?> it = bankAccDetailIdMap.entrySet().iterator(); it
				.hasNext();) {
			Map.Entry e = (Map.Entry) it.next();
			BankAccountDetail bad = bankAccountDetailDaoImpl
					.getBankAccountDetailByID(new BigInteger(e.getKey()
							.toString()));
			voucherAmount = voucherAmount.add(bad.getVoucherAmount());
			bad.setStauts(BankAccountDetail.STATUS_NOCHECK);// 创建时状态为9
			// ，保存时该为2未核实状态
			bankAccountDetailDaoImpl.modifyBankAccountDetail(bad);
		}
		// 销售单总转账凭证金额
		if (voucherAmount.compareTo(tranAmount) < 0) {
			errException("客户购卡总银行转账金额" + get100(voucherAmount)
					+ "不可小于销售单付款总转账金额" + get100(tranAmount) + "!");
		}

		boolean feeAuthOper = false;// 手续费优惠授权
		// 销售单购卡方式 授信购卡
		if (SaleOrder.SaleOrder_PaidType_Credit.equals(saleOrder.getPaidType())) {
			// 计算手续费==计算出来的手续费
			saleOrder.setFee(allFee);
			// 设置销售单总付款金额
			saleOrder.setAlreayPaidAmount(BigInteger.ZERO);
		} else {
			// 转账提醒
			if (saleOrder.getBuyerType().equals(
					SaleOrder.SaleOrder_BuyerType_Person)) {
				if (ic.getPersonTransferLimit() > 0) {
					if (cashAll > ic.getPersonTransferLimit()) {
						errException("个人购卡现金付款" + cashAll / 100 + "超过发卡商转账上限"
								+ ic.getPersonTransferLimit() / 100 + ",必须转账!");
					}
				}

			}
			if (saleOrder.getBuyerType().equals(
					SaleOrder.SaleOrder_BuyerType_company)) {
				if (ic.getOrganizeTransferLimit() > 0) {
					if (cashAll > ic.getOrganizeTransferLimit()) {
						errException("单位购卡现金付款" + cashAll / 100 + "超过发卡商转账上限"
								+ ic.getOrganizeTransferLimit() / 100
								+ ",必须转账!");
					}
				}
			}
			// 手续费=计算出来的手续费
			saleOrder.setFee(allFee);
			// 设置销售单总付款金额
			saleOrder.setAlreayPaidAmount(alreayPaidAmount);
			// 实际授权手续费
			if (saleOrder.getFeeAuthOperId() != null
					&& saleOrder.getFeeAuthOperId().compareTo(BigInteger.ZERO) > 0) {
				// 授权后 将实收手续费赋值给 计算出来手续费合计 计算出来手续费合计不可再赋值给其他字段
				allFee = saleOrder.getFactFee();
				feeAuthOper = true;
			}
			// else {
			// // 未授权实际手续费=计算手续费
			// //saleOrder.setFactFee(saleOrder.getFee());
			// }
			// 手续费
			if (alreayPaidAmount.compareTo(totalSaleAmount.add(allFee)) != 0) {
				errException("销售单应付款和实付款不一致!" + "<br/>总售款："
						+ get100(totalSaleAmount.add(allFee)) + "<br/>"
						+ PCPSUtil.first_Blank + "手续费：" + get100(allFee));
			}
			if (paidAllFee.compareTo(allFee) != 0) {
				errException("销售单已付手续费：" + get100(paidAllFee) + "与计算" + ifplMsg
						+ "手续费：" + get100(allFee) + "不相符");
			}
		}

		boolean autherOper = false;// 大额授权
		// 校验是否输入柜员店长密码 销售单金额不包含手续费金额
		if (ic.getOrderAmountLimit().compareTo(BigInteger.ZERO) > 0
				&& totalSaleAmount.compareTo(ic.getOrderAmountLimit()) > 0) {
			if (saleOrder.getAutherOperId() == null) {
				errException("销售单金额过大,请销售机构主管未授权!");
			}
			if (saleOrder.getAutherOperId().compareTo(webInput.getOperId()) == 0) {
				errException("销售单授权人不能为销售员!");
			}
			autherOper = true;
		}

		// 销售单主键
		BigInteger saleOrderId = commonDaoImpl.getUniqueIntegerKey();
		saleOrder.setSaleOrderId(saleOrderId);

		// 业务单号
		saleOrder.setSaleOrderSeqNo(commonDaoImpl.getOrderNumber(ic
				.getTranDate(), saleBranchNo));
		saleOrder.setTranDate(ic.getTranDate());// 账务日期
		String branchNo = saleOrder.getSaleBranchNo();
		// 插入销售单
		saleOrderDaoImpl.insertSaleOrder(saleOrder);

		// 插入售卡明细
		for (SaleOrderCardDetail socd : insertSocdList) {
			socd.setSaleOrderId(saleOrderId);
			saleOrderCardDetailDaoImpl.insertSaleOrderCardDetail(socd);
			cardStockDaoImpl.updateCardStock(socd.getBatchNo(), socd
					.getStartCardSeqNo(), socd.getEndCardSeqNo(),
					CardStock.CARDSTOCK_STATUS_SALED);
		}
		if (salesDetailList != null) {
			// 插入销售员明细
			for (SaleOrderSalesDetail sosd : salesDetailList) {
				sosd.setSaleOrderId(saleOrderId);
				saleOrderSalesDetailDaoImpl.insertSaleOrderSalesDetail(sosd);
			}
		}
		// 需要插入的实名信息,插入销售单实名明细
		for (Iterator<?> it = insertSorndList.entrySet().iterator(); it
				.hasNext();) {
			Map.Entry e = (Map.Entry) it.next();
			sornd = (SaleOrderRealNameDetail) e.getValue();
			sornd.setSaleOrderId(saleOrderId);
			saleOrderRealNameDetailDaoImpl.insertSaleOrderRealNameDetail(sornd);
		}
		// 插入销售单付款明细
		SaleCapitalDetail insertScd = null;
		SaleOrderPaidDetail insertsopd = null;
		BigInteger insertId = BigInteger.ZERO;
		BigInteger paidCash = BigInteger.ZERO;
		for (int i = 0; i < insertSopdList.size(); i++) {
			insertsopd = insertSopdList.get(i);
			insertId = commonDaoImpl.getUniqueIntegerKey();
			insertsopd.setSaleOrderPaidId(insertId);// 付款主键
			insertsopd.setSaleOrderId(saleOrderId);
			saleOrderPaidDetailDaoImpl.insertSaleOrderPaidDetail(insertsopd);
			insertScd = scdMap.get(i);
			if (insertScd != null) {
				paidCash = paidCash.add(insertsopd.getPaidAmount());
				insertScd.setTicketId(insertId);// 相关业务单ID
				insertScd.setTranTime(now);// 交易时间
				saleCapitalDetailDaoImpl.insertSaleCapitalDetail(insertScd);
			}
		}

		// 销售卡出入库明细
		SaleCardStockDetail scsd = new SaleCardStockDetail();
		SaleOrderCardDetail socd = null;
		for (int i = 0; i < insertSocdList.size(); i++) {
			// 售卡详细信息
			socd = insertSocdList.get(i);
			scsd = new SaleCardStockDetail();
			scsd.setIoOrderId(saleOrderId);
			scsd.setSaleBranchNo(branchNo);
			scsd.setTranDate(ic.getTranDate());// 交易日期
			scsd.setTrantime(now);
			scsd.setTranType(SaleCardStockDetail.SALECARD_TRANTYPE_STOCKOUT);
			scsd.setBatchNo(socd.getBatchNo());
			scsd.setCardStartSeqNo(socd.getStartCardSeqNo());
			scsd.setCardEndSeqNo(socd.getEndCardSeqNo());
			scsd.setOrderCount(socd.getCardCount());
			mcc = makeCardControlDaoImpl.getMakeCardControlByBatchNo(socd
					.getBatchNo());
			if (mcc == null) {
				errException("批次号输入错误，未能找到制卡信息!");
			}
			scsd.setCardFaceId(mcc.getCardFaceId());
			scsd.setOperId(webInput.getOperId());
			scsd.setRemark("销售单出库");
			// 记录销售机构出入库存明细表
			saleCardStockDetailDaoImpl.insert(scsd);
		}
		// 修改销售商分支机构（SaleBranch）现金库存
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchForUpdate(branchNo);
		if (sb == null) {
			errException("销售商分支机构“" + saleBranchNo + "”未找到!");
		}
		sb.setCash(sb.getCash().add(paidCash));
		saleBranchDaoImpl.updateSaleBranch(sb);
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "销售单售卡业务", "销售单流水号：" + saleOrderId);
		// boolean feeAuthOper=false;//手续费优惠授权
		if (feeAuthOper) {
			sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
					SysOperLog.operType_Add, "销售单手续费优惠授权", "销售单流水号："
							+ saleOrderId);
		}
		// boolean autherOper=false;//大额授权
		if (autherOper) {
			sysOperLogDaoImpl
					.insertSysOperLogInfo(webInput, SysOperLog.operType_Add,
							"销售单大额授权", "销售单流水号：" + saleOrderId);
		}
		// 销售单状态迁移明细
		insertSaleOrderActionDetail(saleOrderId, webInput.getOperId(),
				SaleOrder.SALEORDER_ORDERSTATUS_INPUT,
				SaleOrder.SALEORDER_ORDERSTATUS_LIBRARY,
				SaleOrderActionDetail.ACTIONTYPE_OUTOFLIBRARY, "销售单创建");

		return saleOrder;
	}

	private String get100(BigInteger a) {
		DecimalFormat numf = new DecimalFormat();
		double d = Double.parseDouble(a.toString()) / 100;
		numf.applyPattern("#,###,###,##0.00");
		if (d == 0)
			return "0.00";
		else
			return numf.format(d);
	}

	private HashMap<String, SaleOrderRealNameDetail> readRealNameFromExcel(
			BigInteger realNameFileId) throws PCPSApplicationException {
		// 判断是否为空
		BinaryFileInfo file = binaryFileInfoDaoImpl
				.getBinaryFileInfoById(realNameFileId);
		if (file != null && file.getFileLength() > 0) {
			HSSFWorkbook workbook = null;
			InputStream is = null;
			try {
				byte[] xlsfile = file.getFileContent();
				byte[] aResult = new byte[xlsfile.length];
				System.arraycopy(xlsfile, 0, aResult, 0, aResult.length);
				is = new ByteArrayInputStream(aResult);
				workbook = new HSSFWorkbook(is);
			} catch (Exception e) {
				errException("销售单中实名信息excel文件读取异常!");
			}
			List<String[]> readList = new ArrayList<String[]>();
			// 读取excel
			try {
				String line = readLine(workbook);
				int i = 0;
				while (line != null) {
					line = readLine(workbook);
					if (line != null) {
						i++;
						// 不获取第一行表头数据
						if (i > 0) {
							String[] arrStr = line.split("#");
							if (line.indexOf("#") > 0) {
								readList.add(arrStr);
							}
						}
					}
				}
				// 关闭
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						is = null;
					}
				}
				HashMap<String, SaleOrderRealNameDetail> cardRealMap = new HashMap<String, SaleOrderRealNameDetail>();
				// 循环插入持卡人实名明细
				SaleOrderRealNameDetail sornd = null;
				String[] soStr = null;
				// 验证身份证号是否正确
				// IDCardCheck check = new IDCardCheck();
				for (int h = 0; h < readList.size(); h++) {
					sornd = new SaleOrderRealNameDetail();
					soStr = readList.get(h);
					// System.out.println(soStr[0]+"=="+soStr[1]+"==="+soStr[2]+"=="+soStr[3]+"=="+soStr[4]);
					sornd.setBatchNo(soStr[0].trim());
					sornd.setCardSeqNo(soStr[1].trim());
					sornd.setCardNo(soStr[2].trim());
					if (soStr[3] == null || soStr[3].trim().length() < 1
							|| soStr[4] == null || soStr[4].trim().length() < 1) {
						errException("销售单实名excel文件中存在空姓名或身份证号码");
					}
					sornd.setName(soStr[3].trim());// 姓名
					sornd.setIdNo(soStr[4].trim());// 证件号
					// if (!check.Verify(sornd.getIdNo())) {
					// errException("销售单实名excel文件中身份证号"+sornd.getIdNo()+"不合法");
					// }
					cardRealMap.put(sornd.getCardSeqNo(), sornd);
				}
				return cardRealMap;
			} catch (IOException e1) {
				errException("读取销售单实名excel内容异常，请重新导入!");
			}
		} else {
			errException("该销售单无实名excel内容!");
		}
		return null;
	}

	private SaleCapitalDetail getSaleCapitalDetail(
			SaleOrderPaidDetail saleOrderPaidDetail, IssueCompany ic,
			String saleBranchNo, PCPSWebInput webInput)
			throws PCPSApplicationException {
		// 只记录现金账务
		if (saleOrderPaidDetail.getPaidType() != null
				&& (saleOrderPaidDetail.getPaidType()
						.equals(SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH))) {
			// SaleBranch sbs = saleBranchDaoImpl
			// .getSaleBranchBySaleBranchNo(saleBranchNo);
			// 插入销售机构资金明细表（SaleCapitalDetail）
			SaleCapitalDetail scd = new SaleCapitalDetail();
			scd.setSaleBranchNo(saleBranchNo);// 销售机构号
			// CashUpperLimit默认为0，销售单收现金检查，超过该限额提示。
			// if (ic.getCashUpperLimit() != null
			// && ic.getCashUpperLimit().compareTo(BigInteger.ZERO) > 0) {
			// if (saleOrderPaidDetail.getPaidAmount().add(sbs.getCash())
			// .compareTo(ic.getCashUpperLimit()) > 0) {
			// errException("销售单收现后销售机构现金库为"
			// + get100(saleOrderPaidDetail.getPaidAmount().add(
			// sbs.getCash())) + "超过发卡商现金库上限"
			// + get100(ic.getCashUpperLimit()) + ",必须转账!");
			// }
			// }
			scd.setTranDate(ic.getTranDate());
			scd.setTranType(SaleCapitalDetail.TRANTYPE_RECEIVECASH);// 05 – 收到现金
			scd.setCreditDeposit(BigInteger.ZERO);// 信用度存入 decimal(16) Not
			scd.setCreditWithdraw(BigInteger.ZERO);// 信用度支出 decimal(16) Not
			scd.setCashDeposit(saleOrderPaidDetail.getPaidAmount());// 现金存入
			scd.setCashWithdraw(BigInteger.ZERO);// 现金支出 decimal(16) Not Null
			scd.setOperId(webInput.getOperId());// 操作员ID
			scd.setRemark("销售单付款现金记账"); // 摘要
			return scd;
		}
		return null;
	}

	private SaleOrderPaidDetail getSaleOrderPaidDetail(PCPSWebInput webInput,
			SaleOrderPaidDetail saleOrderPaidDetail)
			throws PCPSApplicationException {
		// 对象为NULL
		if (saleOrderPaidDetail == null) {
			errException("销售单付款对象为NULL");
		}
		// 付款类型
		if (saleOrderPaidDetail.getPaidType() == null) {
			errException("销售单付款类型为空!");
		}
		// 非现金付款必输录入付款人和购卡人
		if (!saleOrderPaidDetail.getPaidType().equals(
				SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
			// BankAccDetailId
			if (saleOrderPaidDetail.getBankAccDetailId() == null) {
				errException("非现金购卡时银行转账编号必须填写!");
			}
			BankAccountDetail bad = bankAccountDetailDaoImpl
					.getBankAccountDetailByID(saleOrderPaidDetail
							.getBankAccDetailId());
			if (bad == null) {
				errException("银行转账记账流水未找到!");
			}
			saleOrderPaidDetail.setPayeeAccountId(bad.getBankAccountId());// 发卡商银行信息
			saleOrderPaidDetail.setPaidAccountId(bad.getPaidBankAccountId());// 付款人ID
			saleOrderPaidDetail.setVoucherNo(bad.getVoucherNo());// 凭证号
			saleOrderPaidDetail.setVoucherRemark(bad.getVoucherRemark());// 凭证摘要
			saleOrderPaidDetail.setVoucherImageId(bad.getVoucherImageId());// 凭证图片Id
			// if (saleOrderPaidDetail.getPaidAccountId() == null
			// || saleOrderPaidDetail.getPayeeAccountId() == null) {
			// errException("非现金付款收款人和付款人不可为空!");
			// }
		}

		// 付款金额
		if (saleOrderPaidDetail.getPaidAmount() == null
				|| saleOrderPaidDetail.getPaidAmount().compareTo(
						BigInteger.ZERO) <= 0) {
			errException("付款金额为空或小于0!");
		} else {
			saleOrderPaidDetail.setPaidAmount(saleOrderPaidDetail
					.getPaidAmount());
		}
		return saleOrderPaidDetail;
	}

	/**
	 * @param saleType
	 * @param saleLimit
	 *            销售时限制
	 * @param saleOrderCardDetail
	 * @param saleBranchNo
	 * @return
	 * @throws PCPSApplicationException
	 */
	private SaleOrderCardDetail getSaleOrderCardDetail(String saleType,
			IssueCompany ic, SaleOrderCardDetail saleOrderCardDetail,
			String saleBranchNo) throws PCPSApplicationException {
		// 对象为null
		if (saleOrderCardDetail == null) {
			errException("销售单售卡明细为空!");
		}
		// 起始顺序号
		if (PCPSUtil.isEmpty(saleOrderCardDetail.getStartCardSeqNo())
				|| PCPSUtil.isEmpty(saleOrderCardDetail.getEndCardSeqNo())) {
			errException("售卡顺序号为空!");
		}
		// 售卡面值
		try {
			if (saleOrderCardDetail.getInitDeposit() == null
					|| saleOrderCardDetail.getInitDeposit().intValue() < 0) {
				errException("售卡面值输入有误!");
			}
		} catch (Exception e) {
			errException("售卡面值输入非法!");
		}
		// 非直营时售卡限制
		if (saleType.equals(SaleBranch.SaleBranch_SaleType_Proxy)) {
			// System.out.println(saleOrderCardDetail.getInitDeposit()+"======"+ic.getNonDirectSaleLimit());
			// 单卡销售充值不可大于该限制
			if (ic.getNonDirectSaleLimit().intValue() > 0) {
				if (saleOrderCardDetail.getInitDeposit() > ic
						.getNonDirectSaleLimit()) {
					errException("非直属销售机构不可销售大于" + ic.getNonDirectSaleLimit()
							/ 100 + "面值卡!");
				}
			}
		} else {
			// 直营机构
			if (ic.getEachCardBalanceLimit().compareTo(BigInteger.ZERO) > 0) {
				if (saleOrderCardDetail.getInitDeposit() > ic
						.getEachCardBalanceLimit().intValue()) {
					errException("单卡余额上限为："
							+ get100(ic.getEachCardBalanceLimit()) + " "
							+ "当前售卡面值为" + saleOrderCardDetail.getInitDeposit()
							/ 100 + "已超出上限!");
				}
			}
		}

		// 自动截取卡顺序号
		if (saleOrderCardDetail.getStartCardSeqNo().length() == 18) {
			String batchNo = saleOrderCardDetail.getStartCardSeqNo().substring(
					0, 12);
			if (!batchNo.equals(saleOrderCardDetail.getEndCardSeqNo()
					.substring(0, 12))) {
				errException("录入的终止卡顺序号“"
						+ saleOrderCardDetail.getEndCardSeqNo()
						+ "”和起始卡顺序号不是同一批次的卡!");
			} else {
				saleOrderCardDetail.setBatchNo(batchNo);
			}
		}
		if (saleOrderCardDetail.getStartCardSeqNo().length() == 12) {
			String batchNo = saleOrderCardDetail.getStartCardSeqNo().substring(
					0, 6);
			if (!batchNo.equals(saleOrderCardDetail.getEndCardSeqNo()
					.substring(0, 6))) {
				errException("录入的终止卡顺序号“"
						+ saleOrderCardDetail.getEndCardSeqNo()
						+ "”和起始卡顺序号不是同一批次的卡!");
			} else {
				saleOrderCardDetail.setBatchNo(batchNo);
			}
		}

		// 根据顺序号计算的卡张数
		Integer cardCount = 0;
		try {
			if (saleOrderCardDetail.getEndCardSeqNo().trim().length() < 18) {
				cardCount = Integer.parseInt(saleOrderCardDetail
						.getEndCardSeqNo().substring(6, 12))
						- Integer.parseInt(saleOrderCardDetail
								.getStartCardSeqNo().substring(6, 12));
				cardCount = cardCount + 1;
				saleOrderCardDetail
						.setBatchNo(ic.getIssueCompanyNo()
								+ saleOrderCardDetail.getEndCardSeqNo()
										.substring(0, 6));
			} else {
				cardCount = Integer.parseInt(saleOrderCardDetail
						.getEndCardSeqNo().substring(12, 18))
						- Integer.parseInt(saleOrderCardDetail
								.getStartCardSeqNo().substring(12, 18));
				cardCount = cardCount + 1;
				saleOrderCardDetail.setBatchNo(saleOrderCardDetail
						.getEndCardSeqNo().substring(0, 12));
			}
		} catch (Exception e) {
			errException("卡号段" + saleOrderCardDetail.getStartCardSeqNo() + "到"
					+ saleOrderCardDetail.getEndCardSeqNo() + "输入错误!");
		}
		// 卡张数
		if (saleOrderCardDetail.getCardCount() == null
				|| !saleOrderCardDetail.getCardCount().equals(cardCount)) {
			errException("售卡张数为空或数量错误!");
		}
		// 营销员领卡单单号
		if (!PCPSUtil.isEmpty(saleOrderCardDetail.getSalesGetCardOrderNo())) {
			SalesGetCardOrder sgco = sgcoDaoImpl
					.getSalesGetCardOrderBySalesGetCardOrderNo(saleOrderCardDetail
							.getSalesGetCardOrderNo());
			if (sgco == null) {
				errException("营销员领卡单单号"
						+ saleOrderCardDetail.getSalesGetCardOrderNo() + "有误!");
			}
			// 卡顺序号，卡号
			List<Object[]> stockList = cardStockDaoImpl
					.getCardStockCountBySalesCardOrderId(sgco
							.getSalesGetCardOrderId());
			if (stockList == null) {
				errException("营销员领卡单编号" + sgco.getSalesGetCardOrderId()
						+ "未存在卡库存中");
			}
		} else {
			// 判断卡库存
			HashMap<String, Integer> cardMap = cardStockDaoImpl
					.getCardStockCountBySysbranchnoNoAndStatusAndCredseqno(
							saleOrderCardDetail.getStartCardSeqNo(),
							saleOrderCardDetail.getEndCardSeqNo(),
							CardStock.CARDSTOCK_STATUS_NORMAL, saleBranchNo);
			// 验证输入卡号是否连续，且状态正常
			if (saleOrderCardDetail.getCardCount().intValue() != cardMap.get(
					CardStock.CARDSTOCK_STATUS_NORMAL).intValue()) {
				if (cardMap.size() < 1) {
					errException("卡号段"
							+ saleOrderCardDetail.getStartCardSeqNo() + "至"
							+ saleOrderCardDetail.getEndCardSeqNo() + "不连续!");
				} else {
					errException("卡号段状态异常:" + CardStock.getErrorStatus(cardMap));

				}
			}
		}
		// 计算行内金额 面值*张数，转为分
		try {
			saleOrderCardDetail.setInitDeposit(saleOrderCardDetail
					.getInitDeposit());
			saleOrderCardDetail
					.setOrderLineTotal(new BigInteger(
							String.valueOf((saleOrderCardDetail
									.getInitDeposit() * saleOrderCardDetail
									.getCardCount()))));
		} catch (Exception e) {
			errException("发生异常,销售卡金额合计失败!");
		}
		return saleOrderCardDetail;
	}

	// 校验销售单信息
	private SaleOrder getSaleOrder(PCPSWebInput webInput, SaleOrder saleOrder)
			throws PCPSApplicationException {
		// 插入对象为null
		if (saleOrder == null || webInput.getOperId() == null) {
			errException("销售单录入对象为空或销售操作员为空!");
		}
		if (webInput.getOperId() == null
				|| PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("登录操作员所属销售机构号为空!");
		}
		if (PCPSUtil.isEmpty(saleOrder.getOpenBranchNo())) {
			errException("营销机构为空!");
		} else {
			if (!getSysBranchType(saleOrder.getOpenBranchNo()).equals(
					SysBranch.SYSBRANCH_SALEBRANCH)) {
				errException("营销机构必须为销售机构!");
			}
		}
		SaleBranch sb = null;
		// 营销机构不为当前机构
		if (!saleOrder.getOpenBranchNo().equals(webInput.getOperBranchNo())) {
			// 根据销售机构判断销售商是否激活过期销售机构,销售商过期，销售商下所有分支机构全部过期
			sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(saleOrder
					.getOpenBranchNo());
			if (sb == null) {
				errException("营销机构系统中不存在!");
			} else {
				if (sb.getStatus().equals(
						SaleBranch.SALEBRANCH_STATUS_NOTACTIVATED)) {
					errException("营销机构“" + sb.getSaleBranchName() + "”已停用!");
				}
				if (!getSysBranchType(sb.getSaleBranchNo()).equals(
						SysBranch.SYSBRANCH_SALEBRANCH)) {
					errException("只有销售机构才可售卡!");
				}
				if (sb.getExpired() != null) {
					if (sb.getExpired().before(
							commonDaoImpl.getSysDateFormatYMD())) {
						errException("该销售机构已过期!");
					}
				}
				if (sb.getDayOff().equals(SaleBranch.In_DayOff)) {
					errException("销售机构“" + sb.getSaleBranchName() + "”已经日结!");
				}
			}
		} else {// 营销机构默认为当前销售机构
			// 根据销售机构判断销售商是否激活过期销售机构,销售商过期，销售商下所有分支机构全部过期
			sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(webInput
					.getOperBranchNo());
			if (sb == null) {
				errException("销售机构号系统中不存在!");
			} else {
				if (sb.getStatus().equals(
						SaleBranch.SALEBRANCH_STATUS_NOTACTIVATED)) {
					errException("销售机构“" + sb.getSaleBranchName() + "”已停用!");
				}
				if (!getSysBranchType(sb.getSaleBranchNo()).equals(
						SysBranch.SYSBRANCH_SALEBRANCH)) {
					errException("只有销售机构才可售卡!");
				}
				if (sb.getExpired() != null) {
					if (sb.getExpired().before(
							commonDaoImpl.getSysDateFormatYMD())) {
						errException("该销售机构已过期!");
					}
				}
				if (sb.getDayOff().equals(SaleBranch.In_DayOff)) {
					errException("销售机构“" + sb.getSaleBranchName() + "”已经日结!");
				}
			}
		}
		// 个人购卡
		if (SaleOrder.SaleOrder_BuyerType_Person.equals(saleOrder
				.getBuyerType())) {
			if (saleOrder.getPersonalBuyerId() == null
					&& saleOrder.getProxyBuyerId() == null) {
				errException("个人购卡时购卡人代理人不可都为空！");
			}
		}
		// 单位购卡
		if (SaleOrder.SaleOrder_BuyerType_company.equals(saleOrder
				.getBuyerType())) {
			if (saleOrder.getOrganizeBuyerId() == null
					|| saleOrder.getProxyBuyerId() == null) {
				errException("单位购卡时单位信息与代理人不可为空！");
			}
		}
		// 黑名单验证
		// 个人信息
		if (saleOrder.getPersonalBuyerId() != null) {
			PersonalCustom pc = personalCustomDaoImpl
					.getPersonalCustomByPersonalId(saleOrder
							.getPersonalBuyerId());
			BlackList bk = new BlackList();
			bk.setIdTypeId(pc.getIdTypeId());
			bk.setIdNo(pc.getIdNo());
			BlackList _bl = blackListDaoImpl.getBlackListByBlackList(bk);
			if (_bl != null) {
				errException(_bl.getName() + " 已加入黑名单，禁止购卡!");
			}
		}
		// 代理人信息
		if (saleOrder.getProxyBuyerId() != null) {
			PersonalCustom pc = personalCustomDaoImpl
					.getPersonalCustomByPersonalId(saleOrder.getProxyBuyerId());
			BlackList bk = new BlackList();
			bk.setIdTypeId(pc.getIdTypeId());
			bk.setIdNo(pc.getIdNo());
			BlackList _bl = blackListDaoImpl.getBlackListByBlackList(bk);
			if (_bl != null) {
				errException(_bl.getName() + " 已加入黑名单，禁止购卡!");
			}
		}
		// 操作员号
		saleOrder.setOperId(webInput.getOperId());
		// 销售机构是否直营标示
		saleOrder.setBtnStatus(sb.getSaleType().trim());
		// 押金不可为空
		if (saleOrder.getDepositFee() == null) {
			saleOrder.setDepositFee(BigInteger.ZERO);
		}
		// 创建时累计已核实资金为0
		saleOrder.setTotalCheckAmount(BigInteger.ZERO);
		return saleOrder;
	}

	/**
	 * 判断卡库存状态是否正常
	 * 
	 * @param startCardSeqNo
	 * @param endCardSeqNo
	 * @param status
	 * @param branchNo
	 * @return
	 */
	private boolean checkCardStockStatus(String startCardSeqNo,
			String endCardSeqNo, String status, String branchNo) {
		boolean result = false;
		Integer cardCount = 0;
		if (endCardSeqNo.trim().length() < 18) {
			// 顺序号内卡数量
			cardCount = Integer.parseInt(endCardSeqNo.substring(6, 12))
					- Integer.parseInt(startCardSeqNo.substring(6, 12));
			cardCount = cardCount + 1;
		} else {
			// 顺序号内卡数量
			cardCount = Integer.parseInt(endCardSeqNo.substring(12, 18))
					- Integer.parseInt(startCardSeqNo.substring(12, 18));
			cardCount = cardCount + 1;
		}
		// 详细卡列表
		Integer count = cardStockDaoImpl
				.getCardStockListCountBySaleBranchNoAndStatusAndCredseqno(
						startCardSeqNo, endCardSeqNo, status, branchNo);
		if (!cardCount.equals(count)) {
			result = true;
		}
		return result;
	}

	/**
	 * 销售单撤销 激活的销售单是否能撤销
	 */
	@Override
	public SaleOrder cancelSaleOrder(PCPSWebInput webInput, SaleOrder saleOrder)
			throws PCPSApplicationException {
		if (webInput == null || PCPSUtil.isEmpty(webInput.getOperBranchNo())
				|| webInput.getOperId() == null || saleOrder == null) {
			errException("操作员或销售单参数为空!");
		}
		String cancelRemark = saleOrder.getRemark();
		// 销售单
		SaleOrder _serSO = saleOrderDaoImpl.getSaleOrderBySaleOrderId(saleOrder
				.getSaleOrderId());
		if (_serSO == null) {
			_serSO = saleOrderDaoImpl.getSaleOrderBySaleOrderSeqNo(saleOrder
					.getSaleOrderSeqNo());
		}
		if (_serSO == null) {
			errException("销售单号输入有误,未找到所撤销售单!");
		}
		// 非本人不可撤销
		if (webInput.getOperId().compareTo(_serSO.getOperId()) != 0) {
			errException("销售单只可由创建人撤销!");
		}
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(webInput
				.getOperBranchNo());
		if (sb.getDayOff().equals(SaleBranch.In_DayOff)) {
			errException("销售机构“" + sb.getSaleBranchName() + "”已经日结!");
		}
		BigInteger saleOrderId = _serSO.getSaleOrderId();
		// 已激活的销售单先撤销激活
		// if (_serSO.getOrderStatus().equals(
		// SaleOrder.SALEORDER_ORDERSTATUS_ACTIVATED)) {
		// saleTransBusinessImpl.cancelActivateSaleOrder(webInput,
		// saleOrderId, webInput.getOperId(), cancelRemark);
		// }
		// 已出库状态
		if (!_serSO.getOrderStatus().equals(
				SaleOrder.SALEORDER_ORDERSTATUS_LIBRARY)) {
			errException("非已出库状态销售单不可撤销!");
		}
		// 发卡商
		IssueCompany ic = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(saleOrder.getSaleBranchNo()));
		// 判断是否为日终(交易)状态
		if (ic == null
				|| ic.getStatus().equals(
						IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			errException("销售单所在机构未有归属发卡商或发卡商正在日终禁止操作!");
		}
		// 销售时间
		Date now = commonDaoImpl.getDatabaseSysTime();
		// 销售单售卡信息=============
		List<SaleOrderCardDetail> cardDetailList = saleOrderCardDetailDaoImpl
				.getSaleOrderCardDetailListBySaleOrderId(saleOrderId);
		if (cardDetailList != null && cardDetailList.size() > 0) {
			SaleCardStockDetail scsd = null;
			MakeCardControl mcc = null;
			String stockStatus = CardStock.CARDSTOCK_STATUS_NORMAL;
			for (SaleOrderCardDetail socd : cardDetailList) {
				// 检查状态
				if (checkCardStockStatus(socd.getStartCardSeqNo(), socd
						.getEndCardSeqNo(), CardStock.CARDSTOCK_STATUS_SALED,
						saleOrder.getSaleBranchNo())) {
					errException("待撤销销售单卡状态异常!");
				}
				// 撤销时判断是否营销员领卡
				if (!PCPSUtil.isEmpty(socd.getSalesGetCardOrderNo())) {
					stockStatus = CardStock.CARDSTOCK_STATUS_INTRANSIT;
				}
				// 修改卡状态为 已重新入库待取消销售
				cardStockDaoImpl.updateCardStock(socd.getBatchNo(), socd
						.getStartCardSeqNo(), socd.getEndCardSeqNo(),
						stockStatus);
				// 销售卡出入库明细
				scsd = new SaleCardStockDetail();
				scsd.setIoOrderId(saleOrderId);
				scsd.setSaleBranchNo(_serSO.getSaleBranchNo());
				scsd.setTranDate(ic.getTranDate());// 交易日期
				scsd.setTrantime(now);
				scsd
						.setTranType(SaleCardStockDetail.SALECARD_TRANTYPE_STOCKOUT);// 销售出库撤销
				scsd.setBatchNo(socd.getBatchNo());
				scsd.setCardStartSeqNo(socd.getStartCardSeqNo());
				scsd.setCardEndSeqNo(socd.getEndCardSeqNo());
				scsd.setOrderCount(0-socd.getCardCount());
				mcc = makeCardControlDaoImpl.getMakeCardControlByBatchNo(socd
						.getBatchNo());
				if (mcc == null) {
					errException("批次号输入错误，未能找到制卡信息!");
				}
				scsd.setCardFaceId(mcc.getCardFaceId());
				scsd.setOperId(webInput.getOperId());
				scsd.setRemark("销售单出库撤销");
				// 记录销售机构出入库存明细表
				saleCardStockDetailDaoImpl.insert(scsd);
			}
		}
		// 销售单销售员信息=============
		// List<SaleOrderSalesDetail> salesDetailList =
		// saleOrderSalesDetailDaoImpl
		// .getSaleOrderSalesDetailListBySaleOrderId(saleOrderId);
		// if (salesDetailList != null && salesDetailList.size() > 0) {
		// for (SaleOrderSalesDetail sale : salesDetailList) {
		// // 未处理------------
		// }
		// }

		// 现金付款
		BigInteger paidCash = BigInteger.ZERO;
		// 销售单付款信息=============
		List<SaleOrderPaidDetail> salePaidList = saleOrderPaidDetailDaoImpl
				.getSaleOrderPaidDetailListBySaleOrderId(saleOrderId);
		if (salePaidList != null && salePaidList.size() > 0) {
			SaleOrderPaidDetail insertPaid = null;
			BigInteger insertPaidId = null;
			for (SaleOrderPaidDetail paid : salePaidList) {
				insertPaidId = commonDaoImpl.getUniqueIntegerKey();
				insertPaid = new SaleOrderPaidDetail();
				insertPaid.setSaleOrderPaidId(insertPaidId);// 销售单付款ID
				insertPaid.setTranDate(ic.getTranDate());// 账务日期
				insertPaid.setTranTime(now);// 付款时间
				insertPaid.setSaleOrderId(saleOrderId);// 销售单ID
				insertPaid.setPaidType(paid.getPaidType());// 付款方式
				insertPaid.setPaidClass(paid.getPaidClass());// 付款类型
				insertPaid.setPaidAmount(BigInteger.ZERO.subtract(paid
						.getPaidAmount()));// 付款金额
				insertPaid.setPayeeAccountId(paid.getPayeeAccountId());// 收款人ID
				insertPaid.setPaidAccountId(paid.getPaidAccountId()); // 付款人ID
				insertPaid.setVoucherNo(paid.getVoucherNo());// 凭证号
				insertPaid.setVoucherRemark(paid.getVoucherRemark());// 凭证摘要
				insertPaid.setVoucherImageId(paid.getVoucherImageId());// 凭证图片Id
				insertPaid.setOperId(webInput.getOperId());
				insertPaid.setCancelSaleOrderPaidId(paid.getSaleOrderPaidId());
				insertPaid.setRemark(paid.getRemark());
				// 新插入付款撤销信息
				saleOrderPaidDetailDaoImpl
						.insertSaleOrderPaidDetail(insertPaid);
				// 修改前付款信息
				paid.setCancelSaleOrderPaidId(insertPaidId);

				// 销售机构资金明细表撤销 只记录现金账务 现金账务撤销反记录==============
				if (paid.getPaidType().equals(
						SaleOrderPaidDetail.PAIDDETAIL_PAIDTYPE_CASH)) {
					SaleCapitalDetail insertScd = new SaleCapitalDetail();
					paidCash = paidCash.add(paid.getPaidAmount());
					insertScd.setSaleBranchNo(_serSO.getSaleBranchNo());// 销售机构号
					insertScd.setTranTime(now);
					insertScd.setTranDate(ic.getTranDate());
					insertScd
							.setTranType(SaleCapitalDetail.TRANTYPE_CANCELRECEIVECASH);// 15收到现金取消
					insertScd.setTicketId(insertPaidId);// 业务单号
					insertScd.setCreditDeposit(BigInteger.ZERO);
					insertScd.setCreditWithdraw(BigInteger.ZERO);
					insertScd.setCashDeposit(BigInteger.ZERO.subtract(paid
							.getPaidAmount()));// 现金存入撤销
					insertScd.setCashWithdraw(BigInteger.ZERO);
					insertScd.setOperId(webInput.getOperId());
					insertScd.setRemark("销售单现金记账撤销");
					saleCapitalDetailDaoImpl.insertSaleCapitalDetail(insertScd);
				}

				saleOrderPaidDetailDaoImpl.updateSaleOrderPaidDetail(paid);
			}
		}
		// 实名信息===================
		// List<SaleOrderRealNameDetail> sorndList =
		// saleOrderRealNameDetailDaoImpl
		// .getAllSaleOrderRealNameDetailList(saleOrderId);
		// if (sorndList != null && sorndList.size() > 0) {
		// for (SaleOrderRealNameDetail sornd : sorndList) {
		// // 未处理------------
		// }
		// }

		// 修改销售商分支机构（SaleBranch）现金库存
		SaleBranch sbs = saleBranchDaoImpl.getSaleBranchForUpdate(_serSO
				.getSaleBranchNo());
		if (sbs == null) {
			errException("销售机构“" + _serSO.getSaleBranchNo() + "”未找到!");
		}
		sbs.setCash(sbs.getCash().subtract((paidCash)));
		saleBranchDaoImpl.updateSaleBranch(sbs);
		// 设置撤销参数
		_serSO.setCancelDate(ic.getTranDate());
		_serSO.setCancelTime(commonDaoImpl.getDatabaseSysTime());
		_serSO.setCancelOperId(webInput.getOperId());
		_serSO.setCancelAuthOperId(saleOrder.getCancelAuthOperId());
		_serSO.setOrderStatus(SaleOrder.SALEORDER_ORDERSTATUS_CANCEL);// 46955294
		// 销售单状态迁移明细
		insertSaleOrderActionDetail(saleOrderId, webInput.getOperId(), _serSO
				.getOrderStatus(), SaleOrder.SALEORDER_ORDERSTATUS_CANCEL,
				SaleOrderActionDetail.ACTIONTYPE_BACKTOINPUT, cancelRemark);

		// 执行修改
		saleOrderDaoImpl.updateSaleOrder(_serSO);
		// 插入操作日志
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Edit, "销售单售卡撤销业务", "销售单流水号：" + saleOrderId);

		return _serSO;
	}

	/**
	 * 插入状态迁移明细 状态迁移表操作员号先有前台通过SaleOrder表操作员号字段传入后台
	 * 
	 * @param operId
	 * @param initialStatus
	 * @param endStatus
	 * @param actionType
	 * @param remark
	 * @throws PCPSApplicationException
	 */
	private void insertSaleOrderActionDetail(BigInteger saleOrderId,
			BigInteger operId, String initialStatus, String endStatus,
			String actionType, String remark) throws PCPSApplicationException {
		// 记录状态迁移明细
		SaleOrderActionDetail saleOrderActionDetail = new SaleOrderActionDetail();
		// 销售单号
		saleOrderActionDetail.setSaleOrderId(saleOrderId);
		// 操作时间
		saleOrderActionDetail.setActionTime(commonDaoImpl.getDatabaseSysTime());
		// 状态迁移表操作员号
		saleOrderActionDetail.setOperId(operId);
		// 初始状态
		saleOrderActionDetail.setInitialStatus(initialStatus);
		// 结束状态
		saleOrderActionDetail.setEndStatus(endStatus);
		// ActionType
		saleOrderActionDetail.setActionType(actionType);
		saleOrderActionDetail.setRemark(remark);
		// 插入状态迁移明细
		saleOrderActionDetailDaoImpl
				.insertSaleOrderActionDetail(saleOrderActionDetail);
	}

	// 导入excel
	@Override
	public void importSaleOrderRealNameDetailExcelFile(PCPSWebInput webInput,
			BigInteger saleOrderId, byte[] file)
			throws PCPSApplicationException {
		// 插入对象为null
		if (saleOrderId == null) {
			errException("导入销售单编号为空!");
		}

		// 查询锁定原销售单
		SaleOrder serchSaleOrder = saleOrderDaoImpl
				.getSaleOrderForUpdate(saleOrderId);
		if (serchSaleOrder == null) {
			errException("需要导入的销售单系统中不存在!");
		}
		if (!serchSaleOrder.getOrderStatus().equals(
				SaleOrder.SALEORDER_ORDERSTATUS_INPUT)) {
			errException("只允许在录入状态下导入持卡人实名信息!");
		}
		if (!webInput.getOperBranchNo()
				.equals(serchSaleOrder.getSaleBranchNo())) {
			errException("导入操作员不为当前销售单归属销售机构!");
		}
		// 修改图片
		BigInteger xlsId = binaryFileInfoDaoImpl.insertOrUpdateBinaryFile(file,
				serchSaleOrder.getRealNameFileId(), BinaryFileInfo.XLS);
		serchSaleOrder.setRealNameFileId(xlsId);
		// 修改入数据库
		saleOrderDaoImpl.updateSaleOrder(serchSaleOrder);
	}

	@Override
	public void importExcelFileToSaleOrderRealNameDetail(PCPSWebInput webInput,
			BigInteger saleOrderId) throws PCPSApplicationException {
		// 插入对象为null
		if (saleOrderId == null) {
			errException("需要批量导入持卡人实名信息的销售单编号为空!");
		}
		// 查询销售单
		SaleOrder serchSaleOrder = saleOrderDaoImpl
				.getSaleOrderBySaleOrderId(saleOrderId);
		if (serchSaleOrder == null) {
			errException("需要批量导入持卡人实名信息的销售单系统中不存在!");
		}
		String issueCompanyNo = PCPSUtil.getIssueCompanyNo(webInput);
		if (!issueCompanyNo.equals(serchSaleOrder.getSaleBranchNo().substring(
				0, 6))) {
			errException("无权批量导入其他发卡商下持卡人实名信息!");
		}
		// 判断是否为空
		BinaryFileInfo file = binaryFileInfoDaoImpl
				.getBinaryFileInfoById(serchSaleOrder.getRealNameFileId());
		if (file != null && file.getFileLength() > 0) {
			HSSFWorkbook workbook = null;
			InputStream is = null;
			try {
				byte[] xlsfile = file.getFileContent();
				byte[] aResult = new byte[xlsfile.length];
				System.arraycopy(xlsfile, 0, aResult, 0, aResult.length);
				is = new ByteArrayInputStream(aResult);
				workbook = new HSSFWorkbook(is);
			} catch (Exception e) {
				errException("销售单中实名信息excel文件读取异常!");
			}
			// 里面可以有重复证件号码
			List<String[]> readList = new ArrayList<String[]>();
			// 读取excel
			try {
				String line = readLine(workbook);
				int i = 0;
				while (line != null) {
					line = readLine(workbook);
					if (line != null) {
						i++;
						// 不获取第一行第二行表头数据
						if (i > 1) {
							String[] arrStr = line.split("#");
							if (line.indexOf("#") > 0) {
								readList.add(arrStr);
							}
						}
					}
				}
				// 关闭
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						is = null;
					}
				}
				// 批次号，卡顺序号，卡号，持卡人，证件号
				// 个人可以持有多张卡
				HashMap<String, String> idCardHM = new HashMap<String, String>();
				// 证件号和姓名MAP
				HashMap<String, String> idCardNameHM = new HashMap<String, String>();
				List<String> idCardList = new ArrayList<String>();
				String[] strArr = null;
				for (int k = 0; k < readList.size(); k++) {
					strArr = readList.get(k);
					idCardNameHM.put(strArr[4].trim(), strArr[3].trim());
					idCardHM.put(strArr[4].trim(), strArr[4].trim());// 证件号集合
				}
				// 过滤得到不重复的证件号集合
				for (String str_id : idCardHM.values()) {
					idCardList.add(str_id);
				}
				PersonalCustom pcList = null;
				PersonalCustom pc = null;
				IdType idType = idTypeDaoImpl
						.getIdTypeByIdTypeName(commonDaoImpl.getGlobalInfo()
								.getCommonIdTypeName());
				if (idType == null) {
					errException("证件类型中无身份证一项!");
				}
				// 循环持卡人明细excel,按身份证号码,
				String errCard = "";
				// 身份证号和个人信息编号map
				HashMap<String, BigInteger> pcHp = new HashMap<String, BigInteger>();
				// 需要添加的个人信息
				List<PersonalCustom> insertPCList = new ArrayList<PersonalCustom>();
				// 验证身份证号是否正确
				IDCardCheck check = new IDCardCheck();
				String idCard = "";
				for (int t = 0; t < idCardList.size(); t++) {
					idCard = idCardList.get(t);
					// 根据证件号查询PersonalCustom是否存在
					pcList = personalCustomDaoImpl
							.getPersonalCustomByIdTypeAndIdNo(idType
									.getIdTypeId(), idCard);
					if (pcList == null) {
						// 无个人信息需要添加
						pc = new PersonalCustom();
						pc.setIssueCompanyNo(issueCompanyNo);
						pc.setIdTypeId(idType.getIdTypeId());
						if (!check.Verify(idCard)) {
							errCard += idCard + " ";
						}
						pc.setIdNo(idCard);// 证件号
						pc.setNationCodeId(commonDaoImpl.getGlobalInfo()
								.getChinaNationCodeId());// 国家/地区编码
						pc.setName(idCardNameHM.get(idCard));
						// 需要添加的个人信息
						insertPCList.add(pc);
						// 按姓名匹配没考虑
					} else {
						// 已经存在的个人信息
						pcHp.put(idCard, pcList.getPersonalId());
					}
				}
				// if (!PCPSUtil.isEmpty(errCard)) {
				// errException("错误的身份证号码：" + errCard);
				// }
				PersonalCustom pctom = null;
				// 批量插入个人信息
				PersonalCustom insertPC = null;
				for (int t = 0; t < insertPCList.size(); t++) {
					insertPC = insertPCList.get(t);
					personalCustomDaoImpl.insertPersonalCustom(insertPC);
					pctom = personalCustomDaoImpl
							.getPersonalCustomByIdTypeAndIdNo(idType
									.getIdTypeId(), insertPC.getIdNo());
					pcHp.put(pctom.getIdNo(), pctom.getPersonalId());
				}
				// 循环插入持卡人实名明细
				SaleOrderRealNameDetail sornd = null;
				String[] soStr = null;
				BigInteger personId = BigInteger.ZERO;
				for (int h = 0; h < readList.size(); h++) {
					sornd = new SaleOrderRealNameDetail();
					soStr = readList.get(h);
					sornd.setSaleOrderId(saleOrderId);
					sornd.setBatchNo(soStr[0].trim());
					sornd.setCardSeqNo(soStr[1].trim());
					sornd.setCardNo(soStr[2].trim());
					personId = pcHp.get(soStr[4].trim());
					sornd.setCustomId(personId);// 持卡人参考PersonalCustom
					try {
						saleOrderRealNameDetailDaoImpl
								.insertSaleOrderRealNameDetail(sornd);
					} catch (PCPSApplicationException e) {
						errException("插入个持卡人实名信息失败：" + sornd.getCardSeqNo());
					}
				}
			} catch (IOException e1) {
				errException("读取销售单实名excel内容异常，请重新导入!");
			}
		} else {
			errException("该销售单无实名excel内容!");
		}
	}

	// 当前的Sheet
	private int currSheet;
	// 当前位置
	private int currPosition;

	/**
	 * @param 读取excel中数据
	 *            通过POI提供的API读取文件 只读取第一个sheet中数据
	 * @return
	 */
	private String readLine(HSSFWorkbook workbook) throws IOException {
		// 第一个sheet
		HSSFSheet sheet = workbook.getSheetAt(0);
		// 判断当前行是否到但前Sheet的结尾
		if (currPosition > sheet.getLastRowNum()) {
			// 当前行位置清零,从第一行开始读取
			currPosition = 0;
			// 判断是否还有Sheet
			while (currSheet != 0) {
				// 得到下一张Sheet
				sheet = workbook.getSheetAt(currSheet + 1);
				// 当前行数是否已经到达文件末尾
				if (currPosition == sheet.getLastRowNum()) {
					// 当前Sheet指向下一张Sheet
					currSheet++;
					continue;
				} else {
					// 获取当前行数
					int row = currPosition;
					currPosition++;
					// 读取当前行数据
					return getLine(sheet, row);
				}
			}
			return null;
		}
		// 获取当前行数
		int row = currPosition;
		currPosition++;
		// 读取当前行数据
		return getLine(sheet, row);
	}

	// 函数getLine返回Sheet的一行数据
	private String getLine(HSSFSheet sheet, int row) {
		// 根据行数取得Sheet的一行
		HSSFRow rowline = sheet.getRow(row);
		// 创建字符创缓冲区
		StringBuffer buffer = new StringBuffer();
		// 获取当前行的列数
		int filledColumns = rowline.getLastCellNum();
		HSSFCell cell = null;
		// 循环遍历所有列
		for (int i = 0; i < filledColumns; i++) {
			// 取得当前Cell
			cell = rowline.getCell(i);
			String cellvalue = null;
			if (cell != null) {
				// 判断当前Cell的Type
				switch (cell.getCellType()) {
				// 如果当前Cell的Type为NUMERIC
				case HSSFCell.CELL_TYPE_NUMERIC: {
					// 判断当前的cell是否为Date
					if (HSSFDateUtil.isCellDateFormatted(cell)) {
						// 如果是Date类型则，取得该Cell的Date值
						// Date date = cell.getDateCellValue();
						// 把Date转换成本地格式的字符串
						cellvalue = cell.getDateCellValue().toString();
					}
					// 如果是纯数字
					else {
						// 取得当前Cell的数值
						Integer num = new Integer((int) cell
								.getNumericCellValue());
						cellvalue = String.valueOf(num);
					}
					break;
				}
					// 如果当前Cell的Type为STRING
				case HSSFCell.CELL_TYPE_STRING:
					// 取得当前的Cell字符串
					cellvalue = cell.getStringCellValue().replaceAll("'", "''");
					break;
				// 默认的Cell值
				default:
					cellvalue = "";
				}
			} else {
				cellvalue = "";
			}
			// 在每个字段之间插入分割符
			buffer.append(cellvalue).append("#");
		}
		// 以字符串返回该行的数据
		return buffer.substring(0, buffer.length() - 1);
	}

	/**
	 * 售卡时检查卡是否可卖，获取卡面信息
	 */
	@Override
	public CardFace getSaleOrderCardFace(PCPSWebInput webInput,
			SaleOrderCardDetail socd) throws PCPSApplicationException {
		// 对象为null
		if (webInput == null || socd == null
				|| PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("售卡参数为空!");
		}
		// 起始顺序号
		if (PCPSUtil.isEmpty(socd.getStartCardSeqNo())
				|| PCPSUtil.isEmpty(socd.getEndCardSeqNo())) {
			errException("售卡顺序号为空!");
		}
		if (socd.getStartCardSeqNo().length() != 12
				&& socd.getStartCardSeqNo().length() != 18) {
			errException("售卡顺序号不正确!");
		}
		if (socd.getEndCardSeqNo().length() != 12
				&& socd.getEndCardSeqNo().length() != 18) {
			errException("售卡顺序号不正确!");
		}

		// 自动截取卡顺序号
		if (socd.getStartCardSeqNo().length() == 18) {
			String batchNo = socd.getStartCardSeqNo().substring(0, 12);
			if (!batchNo.equals(socd.getEndCardSeqNo().substring(0, 12))) {
				errException("录入的终止卡顺序号“" + socd.getEndCardSeqNo()
						+ "”和起始卡顺序号不是同一批次的卡!");
			}
		}
		if (socd.getStartCardSeqNo().length() == 12) {
			String batchNo = socd.getStartCardSeqNo().substring(0, 6);
			if (!batchNo.equals(socd.getEndCardSeqNo().substring(0, 6))) {
				errException("录入的终止卡顺序号“" + socd.getEndCardSeqNo()
						+ "”和起始卡顺序号不是同一批次的卡!");
			}
		}

		// 根据顺序号计算的卡张数
		Integer cardCount = 0;
		try {
			if (socd.getStartCardSeqNo().length() == 18) {
				cardCount = Integer.parseInt(socd.getEndCardSeqNo().substring(
						12, 18))
						- Integer.parseInt(socd.getStartCardSeqNo().substring(
								12, 18));
			}
			if (socd.getStartCardSeqNo().length() == 12) {
				cardCount = Integer.parseInt(socd.getEndCardSeqNo().substring(
						6, 12))
						- Integer.parseInt(socd.getStartCardSeqNo().substring(
								6, 12));
			}
			// 起始卡序号不能大于终止卡序号
			if (cardCount < 0) {
				errException("起始卡序号不能大于终止卡序号!");
			}
			cardCount = cardCount + 1;
			socd.setCardCount(cardCount);
		} catch (Exception e) {
			errException("卡号段" + socd.getStartCardSeqNo() + "到"
					+ socd.getEndCardSeqNo() + "输入错误!");
		}

		if (socd.getCardCount() == null || socd.getCardCount().intValue() < 0) {
			errException("售卡张数为空或小于0!");
		}
		String cardStockStatus = CardStock.CARDSTOCK_STATUS_NORMAL;
		HashMap<String, Integer> cardMap = cardStockDaoImpl
				.getCardStockCountBySysbranchnoNoAndStatusAndCredseqno(socd
						.getStartCardSeqNo(), socd.getEndCardSeqNo(),
						cardStockStatus, webInput.getOperBranchNo());
		if (cardMap == null || cardMap.size() < 1) {
			cardStockStatus = CardStock.CARDSTOCK_STATUS_INTRANSIT;
			cardMap = cardStockDaoImpl
					.getCardStockCountBySysbranchnoNoAndStatusAndCredseqno(socd
							.getStartCardSeqNo(), socd.getEndCardSeqNo(),
							cardStockStatus, webInput.getOperBranchNo());
		}
		if (cardMap == null || cardMap.size() < 1) {
			errException("卡号段" + socd.getStartCardSeqNo() + "到"
					+ socd.getEndCardSeqNo() + "库存中不存在!");
		}
		// 验证输入卡号是否连续，且状态正常
		try {
			if (socd.getCardCount().intValue() != cardMap.get(cardStockStatus)
					.intValue()) {
				if (cardMap.size() < 1) {
					throw new CardManaApplicationException(
							PCPSApplicationException.ERRCODE_CATEGORY_APPLICATION,
							"", "卡号段" + socd.getStartCardSeqNo() + "至"
									+ socd.getEndCardSeqNo() + "不连续!");
				} else {
					throw new CardManaApplicationException(
							PCPSApplicationException.ERRCODE_CATEGORY_APPLICATION,
							"", "卡号段状态异常:" + CardStock.getErrorStatus(cardMap));

				}
			}
		} catch (Exception e) {
			// map中如果不存在get状态值抛出异常
			errException("卡号段" + socd.getStartCardSeqNo() + "到"
					+ socd.getEndCardSeqNo() + "库存中不存在!");
		}
		CardStock cs = cardStockDaoImpl.getCardStockByCardseqno(socd
				.getStartCardSeqNo());
		MakeCardControl mcc = makeCardControlDaoImpl
				.getMakeCardControlByBatchNo(cs.getBatchNo());
		CardFace cf = cardFaceDaoImpl.getCardFaceByCardFaceId(mcc
				.getCardFaceId());
		cf.setRemark(mcc.getHintInfo());
		return cf;
	}

	@Override
	public void paySaleOrderCredit(PCPSWebInput webInput,
			SaleOrderPaidDetail sopd) throws PCPSApplicationException {
		// 对象为null
		if (webInput == null || sopd == null
				|| PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("入口参数为空!");
		}
		// 发卡商
		IssueCompany ic = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getIssueCompanyNo(webInput));
		// 判断是否为日终(交易)状态
		if (ic == null
				|| ic.getStatus().equals(
						IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			errException("销售单所在机构未有归属发卡商或发卡商正在日终禁止销售!");
		}
		SaleOrder saleOrder = saleOrderDaoImpl.getSaleOrderBySaleOrderId(sopd
				.getSaleOrderId());
		if (saleOrder == null) {
			errException("销售单未找到或销售单号为空!");
		}
		if (saleOrder.getOrderStatus().equals(
				SaleOrder.SALEORDER_ORDERSTATUS_CANCEL)) {
			errException("销售单[" + saleOrder.getSaleOrderSeqNo() + "]已经被取消!");
		}
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(webInput
				.getOperBranchNo());
		if (sb.getDayOff().equals(SaleBranch.In_DayOff)) {
			errException("销售机构“" + sb.getSaleBranchName() + "”已经日结!");
		}
		// 销售时间
		Date now = commonDaoImpl.getDatabaseSysTime();
		sopd.setTranDate(ic.getTranDate());// 账务日期
		sopd.setTranTime(now);// 付款时间
		BigInteger alreayPaidAmount = saleOrder.getAlreayPaidAmount();
		BigInteger paidAllFee = BigInteger.ZERO;
		Integer cashAll = 0;// 现金购卡金额合计
		// 手续费付款金额
		if (sopd.getPaidClass().equals(
				SaleOrderPaidDetail.PAIDDETAIL_paidClass_fee)) {
			// 已经付的手续费
			BigInteger alreayPaidFee = saleOrderPaidDetailDaoImpl
					.getAlreayPaidAmountBySaleOrderId(saleOrder
							.getSaleOrderId(),
							SaleOrderPaidDetail.PAIDDETAIL_paidClass_fee);
			paidAllFee = sopd.getPaidAmount();
			if (saleOrder.getFactFee().compareTo(alreayPaidFee.add(paidAllFee)) < 0) {
				errException("销售单[" + saleOrder.getSaleOrderSeqNo()
						+ "]手续费已经超过了应付手续费:" + get100(saleOrder.getFactFee())
						+ "元!");
			}
		}
		alreayPaidAmount = alreayPaidAmount.add(sopd.getPaidAmount());
		// 追加付款大于销售单总付款时,报错
		if (alreayPaidAmount.compareTo(saleOrder.getTotalSaleAmount().add(
				paidAllFee)) != 0) {
			errException("销售单应付款和实付款不一致!" + "<br/>总售款："
					+ get100(saleOrder.getTotalSaleAmount().add(paidAllFee))
					+ "<br/>" + PCPSUtil.first_Blank + "手续费："
					+ get100(saleOrder.getFactFee()));
		}
		SaleCapitalDetail scd = getSaleCapitalDetail(sopd, ic, saleOrder
				.getSaleBranchNo(), webInput);
		if (scd != null) {
			cashAll += Integer.parseInt(scd.getCashDeposit().toString());
		}
		// 转账提醒
		if (saleOrder.getBuyerType().equals(
				SaleOrder.SaleOrder_BuyerType_Person)) {
			if (ic.getPersonTransferLimit() > 0) {
				if (cashAll > ic.getPersonTransferLimit()) {
					errException("个人购卡现金付款" + cashAll / 100 + "超过发卡商转账上限"
							+ ic.getPersonTransferLimit() / 100 + ",必须转账!");
				}
			}
		}
		if (saleOrder.getBuyerType().equals(
				SaleOrder.SaleOrder_BuyerType_company)) {
			if (ic.getOrganizeTransferLimit() > 0) {
				if (cashAll > ic.getOrganizeTransferLimit()) {
					errException("单位购卡现金付款" + cashAll / 100 + "超过发卡商转账上限"
							+ ic.getOrganizeTransferLimit() / 100 + ",必须转账!");
				}
			}
		}
		// 设置销售单总付款金额
		saleOrder.setAlreayPaidAmount(alreayPaidAmount);
		saleOrderDaoImpl.updateSaleOrder(saleOrder);

		// 插入销售单付款明细
		BigInteger insertId = BigInteger.ZERO;
		BigInteger paidCash = BigInteger.ZERO;
		insertId = commonDaoImpl.getUniqueIntegerKey();
		sopd.setSaleOrderPaidId(insertId);// 付款主键
		sopd.setSaleOrderId(saleOrder.getSaleOrderId());
		sopd.setOperId(webInput.getOperId());
		saleOrderPaidDetailDaoImpl.insertSaleOrderPaidDetail(sopd);

		if (scd != null) {
			paidCash = paidCash.add(sopd.getPaidAmount());
			scd.setTicketId(insertId);// 相关业务单ID
			scd.setTranTime(now);// 交易时间
			saleCapitalDetailDaoImpl.insertSaleCapitalDetail(scd);
		}
		// 修改销售商分支机构（SaleBranch）现金库存
		SaleBranch sbs = saleBranchDaoImpl.getSaleBranchForUpdate(saleOrder
				.getSaleBranchNo());
		if (sbs == null) {
			errException("销售商分支机构“" + saleOrder.getSaleBranchNo() + "”未找到!");
		}
		sbs.setCash(sbs.getCash().add(paidCash));
		saleBranchDaoImpl.updateSaleBranch(sbs);
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "销售单售卡业务", "销售单流水号："
						+ saleOrder.getSaleOrderSeqNo());
	}

	@Override
	public void cancelSaleOrderCredit(PCPSWebInput webInput,
			SaleOrderPaidDetail sopd) throws PCPSApplicationException {
		// 对象为null
		if (webInput == null || sopd == null
				|| PCPSUtil.isEmpty(webInput.getOperBranchNo())) {
			errException("入口参数为空!");
		}
		sopd = saleOrderPaidDetailDaoImpl
				.getSaleOrderPaidDetailBySaleOrderPaidId(sopd
						.getSaleOrderPaidId());
		if (sopd.getCancelSaleOrderPaidId() != null) {
			errException("此付款信息已被撤销!");
		}
		// 发卡商
		IssueCompany ic = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getIssueCompanyNo(webInput));
		// 判断是否为日终(交易)状态
		if (ic == null
				|| ic.getStatus().equals(
						IssueCompany.ISSUECOMPANY_NORMAL_ENDDAY)) {
			errException("销售单所在机构未有归属发卡商或发卡商正在日终禁止销售!");
		}
		SaleOrder saleOrder = saleOrderDaoImpl.getSaleOrderBySaleOrderId(sopd
				.getSaleOrderId());
		if (saleOrder == null) {
			errException("销售单未找到或销售单号为空!");
		}
		if (saleOrder.getOrderStatus().equals(
				SaleOrder.SALEORDER_ORDERSTATUS_CANCEL)) {
			errException("销售单[" + saleOrder.getSaleOrderSeqNo() + "]已经被取消!");
		}
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(webInput
				.getOperBranchNo());
		if (sb.getDayOff().equals(SaleBranch.In_DayOff)) {
			errException("销售机构“" + sb.getSaleBranchName() + "”已经日结!");
		}
		// 销售时间
		Date now = commonDaoImpl.getDatabaseSysTime();
		SaleOrderPaidDetail csopd = new SaleOrderPaidDetail();
		// 插入销售单撤销付款明细
		BigInteger insertId = BigInteger.ZERO;
		BigInteger paidCash = BigInteger.ZERO;
		insertId = commonDaoImpl.getUniqueIntegerKey();
		csopd.setSaleOrderPaidId(insertId);// 付款主键
		csopd.setTranDate(ic.getTranDate());// 账务日期
		csopd.setTranTime(now);// 撤销时间
		csopd.setSaleOrderId(saleOrder.getSaleOrderId());
		csopd.setPaidType(sopd.getPaidType());
		csopd.setPaidClass(sopd.getPaidClass());
		csopd.setPaidAmount(BigInteger.ZERO.subtract(sopd.getPaidAmount()));
		csopd.setBankAccDetailId(sopd.getBankAccDetailId());
		csopd.setPayeeAccountId(sopd.getPayeeAccountId());
		csopd.setPaidAccountId(sopd.getPaidAccountId());
		csopd.setOperId(webInput.getOperId());
		csopd.setCancelSaleOrderPaidId(sopd.getSaleOrderPaidId());
		csopd.setRemark(sopd.getRemark());
		saleOrderPaidDetailDaoImpl.insertSaleOrderPaidDetail(csopd);

		// 更新被撤销的付款信息
		sopd.setCancelSaleOrderPaidId(insertId);
		saleOrderPaidDetailDaoImpl.updateSaleOrderPaidDetail(sopd);

		// 设置销售单总付款金额
		saleOrder.setAlreayPaidAmount(saleOrder.getAlreayPaidAmount().subtract(
				sopd.getPaidAmount()));
		saleOrderDaoImpl.updateSaleOrder(saleOrder);

		SaleCapitalDetail scd = getSaleCapitalDetail(sopd, ic, saleOrder
				.getSaleBranchNo(), webInput);

		if (scd != null) {
			paidCash = paidCash.subtract(sopd.getPaidAmount());
			scd.setTicketId(insertId);// 相关业务单ID
			scd.setTranTime(now);// 交易时间
			saleCapitalDetailDaoImpl.insertSaleCapitalDetail(scd);
		}
		// 修改销售商分支机构（SaleBranch）现金库存
		SaleBranch sbs = saleBranchDaoImpl.getSaleBranchForUpdate(saleOrder
				.getSaleBranchNo());
		if (sbs == null) {
			errException("销售商分支机构“" + saleOrder.getSaleBranchNo() + "”未找到!");
		}
		sbs.setCash(sbs.getCash().add(paidCash));
		saleBranchDaoImpl.updateSaleBranch(sbs);
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "销售单售卡业务", "销售单付款撤销,流水号："
						+ saleOrder.getSaleOrderSeqNo());
	}
}